禁止拷贝构造赋值函数
来源:互联网 发布:新网域名备案怎么弄 编辑:程序博客网 时间:2024/05/13 12:24
禁止拷贝构造赋值函数
ZZ:http://blog.csdn.net/yanook/article/details/7252843
每个C++类只有一个析构函数,但可以有多个构造函数和多个赋值函数。其中构造函数包括默认构造函数(无参,或参数全有默认值),拷贝构造函数。在编程时,如果程序员不显式声明和定义上述函数,编译器将自动产生4个public inline的默认函数。形式为:
A();
A(const A&);
A& operator=(const A& a)
~A();
【何时需要显式定义拷贝构造函数】
默认的拷贝构造函数和赋值函数,均采用浅拷贝(位拷贝)。拷贝构造函数通过按值传递的方式在函数中传递和返回对象。如果类的成员中有指针的话,这种拷贝方式的结果是两个不同对象的指针指向同一块内存区域,容易出现访问冲突,多次delete等错误,不是我们所希望的。
- class Widget
- {
- public:
- int* pi;
- };
- class Widget
- {
- public:
- int* pi;
- };
- int i1 = 5;
- int i2 = 9;
- Widget w1;
- w1.pi = &i1;
- Widget w2(w1);
- std::cout << *(w2.pi) << std::endl; //output 5
- *(w2.pi) = i2;
- std::cout << *(w1.pi) << std::endl; //output 9
- std::cout << *(w2.pi) << std::endl; //output 9
- int i1 = 5;
- int i2 = 9;
- Widget w1;
- w1.pi = &i1;
- Widget w2(w1);
- std::cout << *(w2.pi) << std::endl; //output 5
- *(w2.pi) = i2;
- std::cout << *(w1.pi) << std::endl; //output 9
- std::cout << *(w2.pi) << std::endl; //output 9
注意 Widget w2 = w1; 是调用了拷贝构造函数,而不是赋值,为避免混淆,最好写成 Widget w2(w1); 可以这么记,调用拷贝构造函数,一定是产生了一个新的对象。
改变对象w2中的pi指针的值,w1中的值也被改掉了,因为两个对象的pi指针指向的都是同一块内存区域。这种错误容易出现在类中定义了缓冲区的情况下。
析构函数、拷贝构造函数和赋值运算符三者几乎总是同时出现。析构函数一般是是为了释放资源,说明类中很有可能定义了指针类型,所以需要显式定义拷贝构造函数和赋值运算符。
【禁止拷贝】
C++ 中用类来表示一类事物,许多类所表示的概念对于“拷贝”这个动作都没有清楚的定义,比如“连接”,“窗口”“文件”等。拷贝一个连接,两个连接的关系是什么?意思是得到了两个参数一样的连接,还是两个对象指向同一个连接?这种情况下,避免二义性,可以通过将拷贝构造函数和重载赋值运算符设为private来禁止拷贝。
- class Widget
- {
- public:
- int* pi;
- private:
- Widget(const Widget&);
- Widget& operator=(const Widget&);
- };
- class Widget
- {
- public:
- int* pi;
- private:
- Widget(const Widget&);
- Widget& operator=(const Widget&);
- };
在VS2010中, 这样声明以后,对上面的测试代码,会提示“no appropriate default constructor available.”
- 禁止拷贝构造赋值函数
- 禁止拷贝构造赋值函数
- 禁止拷贝和赋值构造函数DISABLE_COPY_ADN_ASSIGN
- 禁止拷贝和赋值构造函数
- c++ 禁止拷贝构造函数和赋值构造函数
- 禁止拷贝构造和赋值
- 禁止类的拷贝构造函数和赋值操作符
- 禁止拷贝构造函数
- 拷贝,赋值构造函数赋值
- 赋值函数、拷贝构造函数
- 拷贝构造函数赋值函数
- 拷贝构造函数,赋值函数
- 构造函数 拷贝函数 赋值构造函数
- 构造函数 拷贝函数 赋值构造函数
- 构造函数、拷贝构造函数、赋值函数
- 拷贝构造函数 与 拷贝赋值函数
- 拷贝构造函数和拷贝赋值函数
- 禁止使用拷贝构造函数和赋值函数操作的宏定义
- pat 1011
- NYOJ - 628
- C++----------------->C++模板
- C++抽象基类和纯虚函数
- C++多重继承
- 禁止拷贝构造赋值函数
- C++继承中不能被继承的三个部分
- 九度OJ 题目1188:约瑟夫环
- 计划:数学基础
- sql 存储过程
- zoj 1949 Error Correction
- La (NWERC2007 Problem B )- March of the Penguins(最大流 拆点)
- 金字塔打印
- jdk环境配置