1 设计一个类,不能被拷贝
拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。
- C++98:将拷贝构造函数与赋值运算符重载只声明不定义,并且将其访问权限设置为私有即可。
class HYQ
{
// ...
private:
HYQ(const HYQ&);
HYQ& operator=(const HYQ&);
//...
};
原因:
- 设置成私有:如果只声明没有设置成private,用户自己如果在类外定义了,则不能禁止拷贝了。
- 只声明不定义:不定义是因为该函数根本不会调用,定义了其实也没有什么意义,不写反而还简单。而且如果定义了就不会防止成员函数内部拷贝了。
- C++11
C++11扩展delete的用法,delete除了释放new申请的资源外,如果在默认成员函数后跟上=delete,表示让编译器删除掉该默认成员函数。
class HYQ
{
// ...
HYQ(const HYQ&) = delete;
HYQ& operator=(const HYQ&) = delete;
//...
};
2 设计一个类,只能在堆上创建对象
方案一:析构函数私有化
class HeapOnly
{
public :
// static没有this指针
static void Destroy(HeapOnly* ptr)
{
delete ptr;
}
private:
// 方案一:析构函数私有化
~HeapOnly()
{
cout << " ~HeapOnly()" << endl;
}
};
int main()
{
//HeapOnly hp1;
//Static HeapOnly hp2;
HeapOnly* ptr = new HeapOnly;
// 析构不能用了,如何释放了?
// 答:在类域里面写一个Destroy函数
HeapOnly::Destroy(ptr);
}
class HeapOnly
{
public:
void Destroy()
{
delete this;
}
private:
~HeapOnly()
{
cout << " ~HeapOnly()" << endl;
}
};
int main()
{
HeapOnly* ptr = new HeapOnly;
ptr->Destroy();
}
方案二:构造函数私有化
class HeapOnly
{
public:
// 必须加static,它没有this指针,不需要创建对象去调用
static HeapOnly* CreateObj()
{
return new HeapOnly;
}
HeapOnly(const HeapOnly& hp) = delete;
// 这是为了防止用户在堆上创建对象后
// 通过拷贝的方式绕过我们的限制
// 制造出栈上的临时对象或副本
// 从而破坏了“只能在堆上创建”的设计原则。
private:
HeapOnly()
{
cout << " HeapOnly()" << endl;
}
};
int main()
{
//HeapOnly hp1;
//Static HeapOnly hp2;
//HeapOnly* ptr = new HeapOnly;
// 上面三种都不行了
HeapOnly* ptr = HeapOnly::CreateObj();
// HeapOnly copy(*ptr);
}
3 设计一个类,只能在栈上创建对象
// 请设计一个类,只能在栈上创建对象
class StackOnly
{
public:
static StackOnly CreateObj()
{
StackOnly obj;
return obj;
}
//StackOnly(const StackOnly&) = delete;
void* operator new(size_t size) = delete;
private:
StackOnly()
{
cout << "StackOnly()" << endl;
}
};
int main()
{
StackOnly obj = StackOnly::CreateObj();
// new禁用了,就不能在堆上开空间
//StackOnly* ptr = new StackOnly;
// 但可以这样
// StackOnly* ptr = new StackOnly(obj);
// 除非禁掉operator new
return 0;
}
4 设计一个类,不能被继承
C++98方式:
- 构造函数私有化,派生类中调不到基类的构造函数。则无法继承
C++11方法:
- final关键字,final修饰类,表示该类不能被继承。
class A final
{
// ....
};