`
猫太的鱼
  • 浏览: 241692 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

拷贝构造函数与等号赋值那些事

 
阅读更多
1.我是新手,我会犯错
 32 class Child {
 33     int i;
 34     //Member m;
 35 public:
 36     Child() : i(0) {
 37         cout << "Child()" << endl;
 38     }
 39     
 40     Child(const Child& c) : Parent(c),  i(c.i) {
 41         cout << "Child(const Child&)" << endl;
 42     }
 43     
 44     Child& operator=(const Child& c) {
 45         i = c.i;
 46         cout << "Child& operator=(const Child&)" << endl;
 47     }
 48     ~Child() {
 49         cout << "~Child()" << endl;
 50     }
 51 };
 52 
 53 int main() {
 54     Child c;
 55 
 56     Child c2 = c;
 57     
 58 }


运行这个代码,从得到的结果中可以看出,在代码行Child c2 = c;并没有执行赋值符号中的内容,而是执行了拷贝构造函数中的内容。
为什么呢?这是我这个新手容易犯的错误。虽然Child c2 = c;使用了赋值符号,但是此处是对对象c2的定义,也就是说对象c2在没有被构造之前是不能赋值的,因此,编译器在56行代码处会调用拷贝构造函数,而不是我理解的赋值操作。
因此,为了避免这种二义性,对于对象的定义,在c++中最好使用建议的定义方式,如下面的代码

 53 int main() {
 54     Child c;
 55 
 56     Child c2(c);
 57     
 58 }


2.继承之间的构造函数如何使用
  1 #include <iostream>
  2 using namespace std;
  3 
  4 class Parent {
  5     int i;
  6 public:
  7     Parent() : i(0) {
  8         cout << "Parent()" << endl;
  9     }
 10     Parent(const Parent& p) : i(p.i) {
 11         cout << "Parent(const Parent&)" << endl;
 12     }
 13     ~Parent() {
 14         cout << "~Parent()" << endl;
 15     }
 16 };
 17 
 18 class Member {
 19     int i;
 20 public:
 21     Member() : i(0) {
 22         cout << "Member()" << endl;
 23     }
 24     Member(const Member& m) : i(m.i) {
 25         cout << "Member(const Member&)" << endl;
 26     }
 27     ~Member() {
 28         cout << "~Member()" << endl;
 29     }
 30 };
 31 
 32 class Child : public Parent {
 33     int i;
 34     Member m;
 35 public:
 36     Child() : i(0) {
 37         cout << "Child()" << endl;
 38     }
 39     /*
 40     Child(const Child& c) : Parent(c),  i(c.i) {
 41         cout << "Child(const Child&)" << endl;
 42     }
 43     */
 44     Child& operator=(const Child& c) {
 45         i = c.i;
 46         cout << "Child& operator=(const Child&)" << endl;
 47     }
 48     ~Child() {
 49         cout << "~Child()" << endl;
 50     }
 51 };
 52 
 53 int main() {
 54     Child c;
 55 
 56     Child c2(c);
 57 }

运行结果:
引用
Parent()
Member()
Child()
Parent(const Parent&)
Member(const Member&)
~Child()
~Member()
~Parent()
~Child()
~Member()
~Parent()


可以看到,我们注释了类Child的拷贝构造函数,因此,编译器会默认为我们生成一个类Child的拷贝构造函数,这个函数的只能包括:调用父类的拷贝构造函数,然后调用成员变量的拷贝构造函数(如果存在对象成员变量)。那么,如果我们显示的定义Child的拷贝构造函数呢?


分享到:
评论

相关推荐

    c++中拷贝构造函数实例

    - **拷贝初始化**:通过等号操作符`= new MyClass(obj)`创建对象时,调用的是拷贝构造函数。 - **赋值操作**:而当使用`= operator`为已有对象赋值时,调用的是赋值运算符`=`。这两个过程虽然类似,但不是一回事,...

    拷贝构造函数和赋值操作符号的重载.docx

    在C++编程中,拷贝构造函数和赋值操作符重载是两个非常重要的概念,尤其是在处理包含动态分配资源的对象时。拷贝构造函数和赋值操作符是保证对象正确复制和赋值的关键。 拷贝构造函数是一种特殊的构造函数,其主要...

    构造函数(转)

    3. **复制构造函数(拷贝构造函数)**: - **定义**:其参数为同一类的另一个对象的引用。复制构造函数用于根据已存在的对象创建新的对象。 - **示例**: ```cpp class Complex { public: Complex(const ...

    c++初阶 类和对象 中级篇

    这些默认成员函数包括:默认构造函数、析构函数、拷贝构造函数、赋值运算符重载、等号运算符重载和地址运算符重载。 二、构造函数 构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动...

    浅谈C++中的构造函数分类及调用规则

    4. **默认拷贝构造函数**:默认的拷贝构造函数会简单地按成员变量逐个进行赋值,这可能不适用于复杂的数据类型,因为可能会导致浅复制问题。因此,程序员通常需要自定义拷贝构造函数以实现深复制。 总结来说,一旦...

    详解c/c++赋值函数(重载=号运算符)

    首先c++里的各种运算符都是用函数实现的,比如=,就等号函数。 所以当用=给一个对象赋值的时候,实际调用的是=号所对应的=号函数。 分析下面的代码 ... //拷贝构造函数 Test(const Test &t){ cout &lt;&lt; Co

    C++编程规范1

    - 当定义类类型的变量时,推荐使用直接初始化(直接用花括号 `{}` 初始化)而不是拷贝初始化(用等号 `=` 初始化),以避免不必要的拷贝构造函数调用。 3. **资源管理与特殊函数**: - 对于管理资源的类,如动态...

    林锐《高质量C++C编程指南》

    - **不要轻视拷贝构造函数与赋值函数**:强调了拷贝构造函数和赋值函数的重要性,并举例说明了不当实现可能导致的问题。 - **示例:类STRING的拷贝构造函数与赋值函数**:通过STRING类的示例具体讲解了拷贝构造函数...

    P215~222C++list容器学习笔记.docx

    `:拷贝构造函数。 list容器赋值和交换 list容器提供了多种赋值和交换函数,包括: 1. `assign(beg, end);`:将[beg, end)区间中的数据拷贝赋值给本身。 2. `assign(n, elem);`:将n个elem拷贝赋值给本身。 3. `...

    Cpp面经200问.pdf

    ### C++面经知识点详解 #### 1. main函数前后执行代码 在C++程序中,main函数执行前后会有一些特殊的代码执行。在main执行前,全局变量的构造函数会被调用;而在main函数执行结束后,全局变量的... 拷贝构造函数与赋值...

    P189~196C++string学习笔记.docx

    拷贝构造函数则是将一个 deque 容器拷贝给另一个 deque 容器。 deque 容器的赋值操作包括重载等号操作符、assign 函数和拷贝赋值的方式。assign 函数可以将 [beg, end) 区间中的数据拷贝赋值给本身,或者将 n 个 ...

    林锐 《高质量C/C++编程》

    示例:类String的拷贝构造函数与赋值函数** - 展示如何实现拷贝构造函数和赋值函数的具体方法。 **7. 偷懒的办法处理拷贝构造函数与赋值函数** - 提供一种简化拷贝构造函数和赋值函数实现的方法。 **8. 如何在...

    高质量C_C++编程指南

    - **拷贝构造函数与赋值函数的重要性**:拷贝构造函数和赋值函数对于实现类的深拷贝和浅拷贝至关重要。 - **拷贝构造函数与赋值函数示例**:继续以`STRING`类为例,展示拷贝构造函数和赋值函数的实现。 - **拷贝构造...

    ssd5 Exam 1 Practical

    3. **拷贝构造函数**:`EnhancedSafeArray(const EnhancedSafeArray&)`。该构造函数用于创建一个新的`EnhancedSafeArray`对象,其元素与原对象相同。 4. **获取数组大小的方法**:`int size(void) const`。该方法...

    C++函数返回值为对象时,构造析构函数的执行细节

    如果没有RVO,那么会调用拷贝构造函数`TestConstructor(const TestConstructor&)`来生成这个临时对象,同时析构函数`~TestConstructor()`会被调用来销毁`testInFunc`。 3. **赋值操作**:回到`main()`函数,`test =...

    c++的右值引用具体用法

    传统的C++中,临时对象在使用后会立即被销毁,如果需要继续使用,就需要通过拷贝构造函数或赋值运算符创建新的实例,这可能导致性能上的开销。引入右值引用后,我们可以通过移动构造函数和移动赋值运算符来“移动”...

Global site tag (gtag.js) - Google Analytics