前言:
在C++中有很多关于类的知识,学习并且掌握它们是我们学习C++的重要的一步,怎么检测自己掌握了这些知识呢?请看看尝试解决下面这些问题。
目录
拷贝只会发生在两个场景下,赋值和拷贝构造,因此想要一个类禁止拷贝,只需要让这个类不能调用拷贝构造和赋值运算符重载即可。
在C++98中:会采取拷贝构造函数,和operator=函数私有化的方法来解决这个问题。
- using namespace std;
- class CopyBan
- {
- public:
- CopyBan(int a = 0)
- :_a(a)
- { }
- //...其它实现
-
- private:
- CopyBan(const CopyBan&);
- CopyBan& operator=(const CopyBan&)
- {}
- int _a = 0;
- };
- int main()
- {
- CopyBan cp;
- //拷贝和赋值都会报错
- CopyBan cp1(cp);
- CopyBan cp2;
- cp2 = cp;
- return 0;
- }
在C++11中采用关键字delete。
- class CopyBan
- {
- public:
- CopyBan(int a = 0)
- :_a(a)
- { }
- //...其它实现
- //C++11采用delete关键字
- CopyBan(const CopyBan&) = delete;
- CopyBan& operator=(const CopyBan&) = delete;
-
- private:
-
- int _a = 0;
- };
实现方式:
1.将类的构造函数和拷贝构造函数私有化,防止别人调用它们在其它地方偷偷开辟空间。
2.提供一个静态的成员函数,该静态成员函数完成对象在堆上开辟空间的任务。
- class HeapOnly
- {
- public:
-
- static HeapOnly* CreateObject()
- {
- return new HeapOnly;
- }
- HeapOnly(const HeapOnly&) = delete;
- HeapOnly& operator=(const HeapOnly&) = delete;
- private:
- HeapOnly(int a = 10)
- :_a(a)
- { }
- //int _a;
- int _a;
- };
思路:禁用掉拷贝构造,让构造函数私有化,使用静态方法创建对象返回即可。
- class StackOnly
- {
- public:
- static StackOnly CreateObject(int a = 0)
- {
- return StackOnly();
- }
- private:
-
- StackOnly(int a = 0)
- :_a(a)
- {}
- int _a;
- };
如果只是将operator new定义为已删除函数,不能解决这个问题,因为除了在堆上开辟空间以外,在静态区也是可以开辟对象的。
C++98的做法,构造函数私有化。
- class NonInherit
- {
- //子类继承父类要调用父类的构造函数,如果将构造函数声明为私有,则子类无法调用
- public:
- private:
- NonInherit(int a = 0)
- :_a(a)
- { }
- int _a;
- };
C++11的做法,采用关键字finial ,final修饰类表示这个类不能被继承
- class NonInherit
- {
-
- public:
- NonInherit(int a = 0)
- :_a(a)
- { }
- private:
-
- int _a;
- };