如果一个类的复制静态构造函数声明明为private,那么该类的对象可以执行

以下试题来自:
填空题一般将类的构造方法声明为()访问权限。如果声明为private,就不能创建该类的对象。
public或公有
为您推荐的考试题库
您可能感兴趣的试卷
你可能感兴趣的试题
1.填空题 object2.填空题 接口3.填空题 value4.填空题 死循环5.填空题 常量表达式扫二维码下载作业帮
拍照搜题,秒出答案,一键查看所有搜题记录
下载作业帮安装包
扫二维码下载作业帮
拍照搜题,秒出答案,一键查看所有搜题记录
假定MyClass为一个类,则该类的拷贝构造函数的声明语句为
小简撸过SO
扫二维码下载作业帮
拍照搜题,秒出答案,一键查看所有搜题记录
MyClass(const MyClass&); //拷贝构造函数MyClass::MyClass(const MyClass& RightSides) //拷贝构造函数的定义{nSize=RightSides.nS //复制常规成员pBuffer=new char[nSize]; //复制指针指向的内容memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof(char));}
拷贝构造函数后面的&是什么意思啊
取别名,避免产生新的对象。
如果去掉的话,在执行拷贝构造函数时,先参数RightSides会有个新的对象创建。
这些信息,你可以在构造函数中打印信息,运行,就知道其过程了。
表面上看不出来的。
为您推荐:
其他类似问题
扫描下载二维码笔记十:复制构造函数、深拷贝、浅拷贝
复制构造函数
只有单个形参,而且该形参是对本类类型对象的引用(常用const修饰),这样的构造函数成为复制构造函数。复制构造函数可用于:
1、根据另一个同类型的对象显示或隐式初始化一个对象
2、复制一个对象,将它作为实参传递给一个函数
3、从函数返回时复制一个对象
4、初始化顺序容器中的元素
5、根据元素初始化列表初始化数组元素
&&以上定义来自《C++ Primer 中文版 第4版》
浅拷贝/浅复制
第一条中,若一个自定义类对象已经初始化了,并且用该类去初始化另一个同类类型的对象,假设类中存在指针型变量,若没有显示的构造复制构造函数,那么编译器会自动生成一个复制构造函数,此时的复制称为浅拷贝。
更准确的定义如下:
在C++中,在用一个对象初始化另一个对象时,只复制了成员,并没有复制资源,使两个对象同时指向了同一资源的复制方式称为浅复制。
那么浅拷贝存在的风险是什么呢?
若自定义类中存在指针成员函数,那么:
1、浅拷贝只是复制了指针,使得2个指针指向了同一个地址,这样在对象块结束调用函数析构时,会造成对同一资源的2次析构,即delete 2次,引起程序崩溃。
2、浅拷贝使得2个指针成员指向同一个内存地址,修改其中一个指针指向的值,会改变另一个对象的指针指向的值
3、在内存释放时,作为实参传递的类由于析构不成功,造成内存泄露。
通过一个实例来反应:
cout && data &&
cout && &默认构造函数& &&
cout && &析构函数& &&
cout && data &&
data = NULL;
int main(int argc, char* argv[])
针对以上代码,进行单步,逐语句的调试:
1、在A 处设置断点,采取逐语句F11调试,进入到自定义构造函数中:
2、对于对象a&&动态分配一个内存给data,此时data的值为0x,存储data这个值得内存地址为0x002ffbf4 :
3、继续执行F11,会发现程序不会再次进入到自定义构造函数,因为此时A b(a) 执行的复制构造函数,由于类没有显示定义,故由编译器自动完成,程序运行到:
4、在main函数结束之前,由于对象的声明周期已到,故此时需调用析构函数,且析构函数的顺序是由后往前析构,即对象b在对象a之后定义,那么b在a之前析构。通过观察也可以判断析构顺序,此时存储data变量的地址为0x002ffbe8 与a中存储data的地址不同。
但是a, b中data值均为0xvcD4NCjxwPjxpbWcgYWx0PQ=="这里写图片描述" src="/uploadfile/Collfiles/95.png" title="\" />
5、delete释放掉内存资源后,data的值变为0x&字符串中的字符无法&&:( 个人理解,这里的0x&字符串中的字符无法&& 与0x&妄&&有本质区别,后者内存地址对应着一个实际的内存空间,内存中存储的数据显示乱码。而前者尽管看似为一个内存地址值,但并未对应到一个实际的内存空间,好比一个学号之前是可以对应一个学生的,但是学生信息注销之后,尽管该学号存在,但是无法查找到此人。若理解有误,恳请指正,虚心学习~) ,此时data成为一个垂悬指针。
6、避免垂悬指针的存在,将指针指向NULL:
7、第一次析构结束:
8、第2次析构,即对象a的析构。此时可以观察到data存储的值已经变为0x&字符串中的字符无法&&,即data是一个野指针了。
9、继续析构,则导致程序崩溃:
上述调试则解释了浅拷贝可能造成的影响即:
1、同一内存空间析构2次引起程序崩溃
2、一个类成员修改资源,会使得另一个也随之改变
3、第3点有疑问,data指向的内存存储在堆中,但是已经由对象b给释放了,而data是一个局部变量,其储存地址在栈中,程序结束,系统自动收回栈中的资源,那么此时所谓的内存泄露是泄露了哪一部分内存资源呢???表示不太理解,或许我理解有误???
深拷贝/深复制
当拷贝对象中有对其他资源(如堆、文件、等)的引用时(引用可以是指针或引用)时,对象另开辟一块新的资源,而不再对拷贝对象中资源的指针或引用进行单纯的赋值。简单地说,即是非共享同一块内存资源,而是重新开辟一块内容,将数据复制到新开辟的内存中。
通过一个实例来反应:
cout && data &&
cout && &默认构造函数& &&
A(const A& a)
memcpy(data, a.data, sizeof(a.data));
cout && &析构函数& &&
cout && data &&
data = NULL;
int main(int argc, char* argv[])
采用单步调试F11:
1、程序执行到对象a的实例化:
2、进入对象a的构造函数中:
3、此时在堆中为data开辟了一个内存,内存地址为0x
4、注意,在浅复制时,程序直接运行到return 0; 。而深复制,F11后进入复制构造函数:
5、观察此时data指向的内存地址为0x00558d10 与a.data(0x)是不同的。memcpy的目的即为复制数据。
6、执行对象b的析构,此时data的值为0x00558d10,正好是b对象复制构造中分配的内存空间的地址。
7、此时对象b占据的堆中的资源被释放。
8、第2次析构,即a对象中资源的释放,此时data的值为0x
9、程序没有出现崩溃的状况,表明2次析构成功。
那么,什么时候用浅拷贝?什么时候用深拷贝呢?
最好使用深拷贝或智能指针。深拷贝相对于浅拷贝来说,会占据额外的内存资源,但是使用更加安全。构造函数定义为private,protected - 原来... - 博客园
将构造函数,析构函数声明为私有和保护的,那么对象如何创建?
已经不能从外部调用构造函数了,但是对象必须被构造,应该如何解决,麻烦大家帮忙说明,关于构造,析构函数声明为私有和保护时的用法???
提出这个问题,说明你已经对c++有所思考了。
从语法上来讲,一个函数被声明为protected或者private,那么这个函数就不能从&外部&直接被调用了。
对于protected的函数,子类的&内部&的其他函数可以调用之。
而对于private的函数,只能被本类&内部&的其他函数说调用。
语法上就是这么规定的,你肯定也知道的咯。
那么为什么有时候将构造函数或者析构函数声明为protected的或者private的?
通常使用的场景如下:
1。如果你不想让外面的用户直接构造一个类(假设这个类的名字为A)的对象,而希望用户只能构造这个类A的子类,那你就可以将类A的构造函数/析构函数声明为protected,而将类A的子类的构造函数/析构函数声明为public。例如:
{ protected: A(){}
public: ....
calss B : public A
{ public: B(){}
A // error
2. 如果将构造函数/析构函数声明为private,那只能这个类的&内部&的函数才能构造这个类的对象了。这里所说的&内部&不知道你是否能明白,下面举个例子吧。
void Instance()//类A的内部的一个函数
上面的代码是能通过编译的。上面代码里的Instance函数就是类A的内部的一个函数。Instance函数体里就构建了一个A的对象。
但是,这个Instance函数还是不能够被外面调用的。为什么呢?
如果要调用Instance函数,必须有一个对象被构造出来。但是构造函数被声明为private的了。外部不能直接构造一个对象出来。
A aO // 编译通不过
aObj.Instance();
但是,如果Instance是一个static静态函数的话,就可以不需要通过一个对象,而可以直接被调用。如下:class A
A():data(10){ cout && "A" && }
~A(){ cout && "~A" && }
static A& Instance()
void Print()
cout && data &&
A& ra = A::Instance();
ra.Print();
上面的代码其实是设计模式singleton模式的一个简单的C++代码实现。
还有一个情况是:通常将拷贝构造函数和operator=(赋值操作符重载)声明成private,但是没有实现体。
这个的目的是禁止一个类的外部用户对这个类的对象进行复制动作。
细节请看《effective C++》里面的一个条款。具体哪个条款不记得了。
随笔 - 210

我要回帖

更多关于 静态构造函数声明 的文章

 

随机推荐