【C++】单例模式编程实验

任务

任务:单件模式是一种用于确保整个应用程序中只有一个类实例的程序设
计方法。

请编写程序,设计并实现单例类,以完成以下功能:

  1. 外部不能够任意实例化该类的对象;
  2. 只能够通过该类的静态成员函数 Singleton::GetInstance()获得该类的唯一
    对象,换言之,在任何地方通过该静态成员函数获得对象指针都是指向同一个
    对象。
  3. 设计该类的成员变量 string name 以及相应的成员函数(set/get 函数)对
    对象的唯一性进行验证。

解答

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//main.cpp

#include<iostream>
#include "Singleton.h"

using namespace std;

void fun(){
Singleton *s = Singleton::GetInstance();
s->SetName("Bob");//题目给定
}

int main()
{
Singleton * t = Singleton:: GetInstance();
t->SetName("Alice");
fun();
cout<<t->GetName()<<endl;
return 0;
}//题目给定

Singleton.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <string>
using namespace std;

class Singleton{
public:
static Singleton *GetInstance();
void SetName(const char *s);
string GetName();

private:
Singleton();
static Singleton *_instance;
string name;
};//类的定义,string类型必须要引用string

Singleton* Singleton::_instance=nullptr;
//类外初始化

Singleton::Singleton(){}
//构造函数

Singleton* Singleton::GetInstance(){
if(_instance == nullptr)
_instance = new Singleton;
return _instance;
}//查找_instance是否创建,没创建新建一个,创建了返回地址

void Singleton::SetName(const char* s){
name = s;
}//更改类中name

string Singleton::GetName(){
return name;
}//获取name

出现过问题

判断写成了赋值

if判断中的等于判断==,失手写成了赋值=

错误的引用string

报错:声明与 "<error-type> Singleton::GetName()" (已声明 所在行数:27,所属文件:"C:\USERS\FENG\DESKTOP\C++\第二次实验\Singleton.h") 不兼容

Singleton.h头文件中没有包含<string>using namespace std;

没有进行类外初始化!

报错:

1
2
C:\Users\Feng\AppData\Local\Temp\ccfhC9e4.o:main.cpp:(.rdata$.refptr._ZN9Singleton9_instanceE[.refptr._ZN9Singleton9_instanceE]+0x0): undefined reference to `Singleton::_instance'
collect2.exe: error: ld returned 1 exit status

一定要进行类外初始化!

static静态成员一定要进行类外初始化!

1
Singleton* Singleton::_instance=nullptr;

为什么一定要初始化

static数据成员在类外定义和初始化是为了保证只被定义和初始化一次,这样编译器就不必考虑类的函数里面第一个对static变量的=操作是赋值还是初始化了。 static const int可以在类里面初始化,是因为它既然是const的,那程序就不会再去试图初始化了。

为什么一定要类外

因为静态成员属于整个类,而不属于某个对象,如果在类内初始化,每次新建对象都会创建一个静态成员,导致每个对象都包含该静态成员,这是矛盾的!