学习资料

• 派生类的赋值运算符/赋值构造函数也必须处理它的基类成员的赋值

• C++ 基类构造函数带参数的继承方式及派生类的初始化

定义拷贝构造函数

【注意】对派生类进行拷贝构造时,如果想让基类的成员也同时拷贝,就一定要在派生类拷贝构造函数初始化列表中显示调用基类拷贝构造函数(当然在函数体内将基类部分的值拷贝也是可以的,只不过它是先用默认构造函数初始化后再修改的基类成员变量的值,效率比较低),否则它会调用基类的默认构造函数,而不会对基类的成员变量拷贝值,这样生成的对象,它的派生类部分和被拷贝的对象派生类部分一样,而基类部分则是默认构造函数的初始化结果。

代码例子1:

 1 #include <iostream>
 2 using namespace std;
 3
 4 class A
 5 {
 6 public:
 7     A() { cout << "A default constructor" << endl; }
 8     A(A&) { cout << "A copy constructor" << endl; }
 9 };
10 class B : public A
11 {
12 public:
13     B() { cout << "A default constructor" << endl; }
14     B(B &b) { cout << "B copy constructor" << endl; }
15 };
16
17 int main()
18 {
19     B b;
20     B c = b;
21     return 0;
22 }

输出结果:

代码例子2:

 1 #include <iostream>
 2 using namespace std;
 3
 4 class A
 5 {
 6 public:
 7     A() { cout << "A default constructor" << endl; }
 8     A(A&) { cout << "A copy constructor" << endl; }
 9 };
10 class B : public A
11 {
12 public:
13     B() { cout << "A default constructor" << endl; }
14     B(B &b) : A(b) { cout << "B copy constructor" << endl; }
15 };
16
17 int main()
18 {
19     B b;
20     B c = b;
21     return 0;
22 }

输出结果:

C++ 基类构造函数带参数的继承方式及派生类的初始化

在定义类的时候,会遇到基类的构造函数带参数,而子类子类构造函数不带参数,这时候如果以代码 a 的方式建立派生类则会出错。

 1 class A
 2 {
 3     public:
 4         A(int x, int y): i(x), j(y) {}
 5     private:
 6         int i, j;
 7 };
 8
 9 class B : public A
10 {
11     public:
12         B() { cout << "init B" << endl; }
13 };

在建立B类对象时,编译出错: 
 C:\Documents and Settings\admin\桌面\Text1.cpp(104) : error C2512: ‘A’ : no appropriate default constructor available

解决这个问题应该在A的构造函数中显式调用基类的带参构造函数。因为在基类中定义了带参构造函数,编译器不会提供默认构造函数。(或者可以在基类中增加一个不带参数的构造函数)这个问题将解决。 
代码 b 采用的是调用基类带参构造函数的方式:

代码 b:

 1 class A
 2 {
 3     public:
 4         A(int x, int y): i(x), j(y) {}
 5     private:
 6         int i, j;
 7 };
 8
 9 class B : public A
10 {
11     public:
12         B() A(10,20) { cout << "init B" << endl; }
13 };

通过在基类中增加一个不带参数的构造函数: 
代码 c:

 1 class A
 2 {
 3     public:
 4         A(int x, int y): i(x), j(y) {}
 5         A();   //不带参数的构造函数
 6     private:
 7         int i, j;
 8 };
 9
10 class B:public A
11 {
12     public:
13         B(): A(10,20) { cout << "init B" << endl; }
14 };

定义派生类赋值运算符

与拷贝和移动构造函数一样,派生类的赋值运算符也必须为其基类部分赋值。

1 // Base::operator=(const Base&) 不会被自动调用
2 D& D::operator=(const D &rhs)
3 {
4     Base::operator=(rhs);  //为基类部分赋值
5     //按照过去的方式为派生类的成员赋值
6     return *this;
7 }

举例说明:

 1 class base
 2 {
 3 public:
 4   base(int initialvalue = 0): x(initialvalue) {}
 5
 6 private:
 7   int x;
 8 };
 9
10 class derived : public base
11 {
12 public:
13   derived(int initialvalue): base(initialvalue), y(initialvalue) {}
14   derived& operator=(const derived& rhs);
15
16 private:
17   int y;
18 };
19
20 逻辑上说,derived的赋值运算符应该象这样:
21 derived& derived::operator = (const derived& rhs) // 错误的赋值运算符
22 {                                                 // 请注意d1的base部分没有被赋值操作改变。
23   if (this == &rhs)
24     return *this;
25   y = rhs.y;
26   return *this;
27 }
28
29 不幸的是,它是错误的,因为derived对象的base部分的数据成员x在赋值运算符中未受影响。例如,考虑下面的代码段:
30
31 void assignmenttester()
32 {
33   derived d1(0);      // d1.x = 0, d1.y = 0
34   derived d2(1);      // d2.x = 1, d2.y = 1
35
36   d1 = d2;            // d1.x = 0, d1.y = 1
37 }
38
39
40 derived& derived::operator = (const derived& rhs) // 正确的赋值运算符
41 {
42   if (this == &rhs)
43     return *this;
44
45   base::operator = (rhs);    // 调用this->base::operator=
46   y = rhs.y;
47
48   return *this;
49 }

转载于:https://www.cnblogs.com/sunbines/p/9215310.html

【C++ Primer 第15章】定义派生类拷贝构造函数、赋值运算符相关推荐

  1. 定义派生类拷贝构造函数

    2019独角兽企业重金招聘Python工程师标准>>> 如果派生类定义了自己的拷贝构造函数,该拷贝构造函数一般应显式的使用基类的拷贝构造函数初始化对象的基类部分 class Base ...

  2. C++派生类的构造函数和析构函数

    C++派生类的构造函数和析构函数 派生类的构造函数和析构函数 #include <iostream> using namespace std; class student { public ...

  3. C++ Primer 5th笔记(chap 15 OOP)派生类的拷贝控制成员

    当派生类定义了拷贝.赋值.移动操作时,该操作负责拷贝.赋值.移动包括基类部分成员在内的整个对象. 1.1 定义派生类的拷贝或移到构造函数 class Base { /* ... */ };class ...

  4. C++Primer 第15章 OOP

    C++Primer 第15章 OOP #include<iostream> class Base {public:virtual void fun1(int i = 0){std::cou ...

  5. 基类成员的public访问权限在派生类中变为_C++ 派生类的构造函数(学习笔记:第7章 06)...

    派生类的构造函数[1] 默认情况 基类的构造函数不被继承; 派生类需要定义自己的构造函数. C++11规定 可用using语句继承基类构造函数. 但是只能初始化从基类继承的成员. 派生类新增成员可以通 ...

  6. C++ primer 第15章 面向对象程序设计

    文章目录 前言 OOP:概述 继承 动态绑定 定义基类和派生类 定义基类 成员函数与继承 访问控制与继承 定义派生类 派生类中的虚函数 派生类对象及派生类向基类的类型转换 派生类构造函数 派生类使用基 ...

  7. 声明一个国家基类Country,包含国名、首都、人口等属性,派生出省类Province,增加省会城市、人口数量属性。定义派生类对象,并对相应信息进行输出

    声明一个国家基类Country,包含国名.首都.人口等属性,派生出省类Province,增加省会城市.人口数量属性.定义派生类对象,并对相应信息进行输出. # include<iostream& ...

  8. c++, 派生类的构造函数和析构函数 , [ 以及operator=不能被继承 or Not的探讨]

    说明:文章中关于operator=实现的示例,从语法上是对的,但逻辑和习惯上都是错误的. 参见另一篇专门探究operator=的文章:<c++,operator=>http://www.c ...

  9. C++中基类与派生类的构造函数和析构函数

    1.Cpp中的基类与派生类的构造函数 基类的成员函数可以被继承,可以通过派生类的对象访问,但这仅仅指的是普通的成员函数,类的构造函数不能被继承.构造函数不能被继承是有道理的,因为即使继承了,它的名字和 ...

最新文章

  1. java 方块_哈工大java实验 移动小方块
  2. Python中装饰器的理解和实现
  3. scala从集合中提取不重复的元素
  4. Class.forName()和ClassLoader.getSystemClassLoader().loadClass()区别
  5. c++ for循环 流程图_python 零基础必知--条件控制与循环语句
  6. 前端学习(1255):promise用法
  7. python pca降维_机器学习的降维打击
  8. win7系统任务管理器被禁用怎么解决
  9. 函数的作用域以及预编译
  10. oc 画一个圆弧_SolidWorks一步扫描特征,就可以画出一个螺母,你有思路吗
  11. 继承Thread类的方式创建多线程
  12. 全国高校计算机能力挑战赛真题(二)
  13. 使用JS制作一个鼠标可拖的DIV(二)——限制区域移动
  14. nodejs+socket.io用nginx反向代理提示400 Bad Request及ws://…无法连接的解决方法
  15. Python中系统命令
  16. 硬件科普系列之硬盘——总线、协议、接口和固态硬盘篇
  17. ThinkPHP6项目基操目录
  18. 何洛洛高考成绩查询2021,2021高考查分时间表 什么时候查成绩
  19. 2022-2028全球及中国铝硅合金电子封装材料行业研究及十四五规划分析报告
  20. C++中内存块置0的三种方法:memset, ZeroMemory和SecurZeroMemory

热门文章

  1. 汇编的8种寻址方式,以及2个默认段寄存器
  2. 手工编译Android程序
  3. golang使用gdb
  4. 网络基准测试Netperf
  5. MySQl笔记7:MySQL在线模拟平台汇总
  6. linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗?
  7. 常考数据结构与算法:最小的k个数
  8. 微信XML,Object,MAP相互转换
  9. jsp页面遍历后台传递的对象
  10. Design Pattern: Singleton 模式