C++学习-派生类的复制运算符

原创 2015年07月07日 08:27:50

派生类的赋值控制函数

        派生类构造函数在其初始化阶段不仅要初始化类自己的成员,还负责初始化派生类对象的基类部分。因此,派生类的复制控制函数在复制自有成员的同时,也要复制基类部分的成员。类似的,如果派生类的赋值运算符没有处理基类的相应的部分,则派生类中基类的部分会采用默认值,请看下面的程序

#include <iostream>

using namespace std;

class Base
{
public:
    Base() { p1 = new int; *p1 = 1; cout << "Base::Base()" << endl; }
    ~Base() { delete p1; cout << "Base::~Base()" << endl; }
    Base& operator=(const Base &b) { cout << "Base::operator=()" << endl; p1 = new int; *p1 = *b.p1; return *this; }
    int *p1;
};

class Derived : public Base
{
public:
    Derived() { p2 = new int; *p2 = 2; cout << "Derived::Derived()" << endl; }
    ~Derived() { delete p2; cout << "Derived::~Derived()" << endl; }
	Derived & operator=(Derived &d) { cout << "Derived::operator=()" << endl; p2 = new int; *p2 = *d.p2; return *this;}
    int *p2;
};

int main(void)
{
    Derived d;
    *d.p1 = 3;
    *d.p2 = 4;

    cout << "d.p1: " << *d.p1 << endl;
    cout << "d.p2: " << *d.p2 << endl;

	//Derived d2 = d; //注意:此时调用的不是赋值运算符,而是d2的复制构造函数!!!
	Derived d2;
	d2 = d;
    cout << "d2.p1: " << *d2.p1 << endl;
    cout << "d2.p2: " << *d2.p2 << endl;

    *d2.p1 = 5;
    *d2.p2 = 6;
    cout << endl;
    cout << "d.p1: " << *d.p1 << endl;
    cout << "d.p2: " << *d.p2 << endl;
    cout << "d2.p1: " << *d2.p1 << endl;
    cout << "d2.p2: " << *d2.p2 << endl;

    return 0;
}
输出结果为

        在没有给d2中的p1和p2重新赋值前,d2的*p1为1而不是为3,显然和我们想要的结果不一致。。。

派生类的赋值运算符也必须地显式为基类部分赋值:

//Base::operator=(const Base&)不会被自动调用
Derived &Derived::operator=(const Derived &d)
{
	Base::operator=(d); //为基类部分赋值
	p2 = new int; 
	*p2 = *d.p2;
	return *this;
}

更改后的完整程序

#include <iostream>

using namespace std;

class Base
{
public:
    Base() { p1 = new int; *p1 = 1; cout << "Base::Base()" << endl; }
    ~Base() { delete p1; cout << "Base::~Base()" << endl; }
    Base& operator=(const Base &b) { cout << "Base::operator=()" << endl; p1 = new int; *p1 = *b.p1; return *this; }
    int *p1;
};

class Derived : public Base
{
public:
    Derived() { p2 = new int; *p2 = 2; cout << "Derived::Derived()" << endl; }
    ~Derived() { delete p2; cout << "Derived::~Derived()" << endl; }
	Derived & operator=(Derived &d) { cout << "Derived::operator=()" << endl; p2 = new int; *p2 = *d.p2; return *this;}
    int *p2;
};

int main(void)
{
    Derived d;
    *d.p1 = 3;
    *d.p2 = 4;

    cout << "d.p1: " << *d.p1 << endl;
    cout << "d.p2: " << *d.p2 << endl;

	//Derived d2 = d; //注意:此时调用的不是拷贝控制函数,而是d2的默认复制构造函数
	Derived d2;
	d2 = d;
    cout << "d2.p1: " << *d2.p1 << endl;
    cout << "d2.p2: " << *d2.p2 << endl;

    *d2.p1 = 5;
    *d2.p2 = 6;
    cout << endl;
    cout << "d.p1: " << *d.p1 << endl;
    cout << "d.p2: " << *d.p2 << endl;
    cout << "d2.p1: " << *d2.p1 << endl;
    cout << "d2.p2: " << *d2.p2 << endl;

    return 0;
}
这样就和我们想要的结果一致了大笑


参考

        1、《C++ Prime》 第5版 15.7 构造函数与拷贝控制

C++学习笔记:3.3.6 派生类中的static关键字

继承和static关键字在一起会产生什么现象呢? 理论知识: 1.基类定义的静态成员,将被所有派生类共享 2.根据静态成员自身的访问特性和派生类的继承方式,在类层次体系中具有不同的访问性质(遵守...

C++学习笔记-----永远不要在派生类中改变虚函数的默认参数值

提到虚函数,我们就会自然而然的想到多态,但是当虚函数中存有默认参数值的时候,在派生类中重定义这个虚函数时不可以改变这个参数的值。 请看下面的例子: #include "stdafx.h" #inclu...

C++学习(1)--基类、派生类的对象空间

#include #include using namespace std; //基类 class CMyBase { int x; int y; public: int S...

C++学习基础之基类和派生类

派生类的继承方式总结: 继承方式 说明 public 基类的public和protected的成员被派生类继承后,保持原来的状态 privat...

C++之派生类的拷贝构造与赋值运算符重载

这里只说一下为什么派生类在拷贝构造器和赋值运算符重载中一些注意语法: 一、派生类的拷贝构造器1.派生类的拷贝构造器跟普通构造器一样,若没有自定义生成,编译器会自动生成拷贝构造器,自动调用父类的拷贝构...

C++学习笔记(四)类的解释及使用/setf( )函数/作用域解析运算符

C++通过一些特性改进了C语言,使得OOP应用得更容易,下面是最重要的OOP特性: 抽象 封装和数据隐藏 多态 继承 代码的重用性 为帮助识别类,一般C++程序员习惯将类名首字母大写 如...
  • KXZKXZZ
  • KXZKXZZ
  • 2017年07月19日 17:33
  • 66

c++学习笔记5:运算符重载、友元和类的类型转换

1. 运算符重载 1.1 运算符函数的声明 class Time { public: Time operator+(const Time & t)const; }; Time T...

c++学习笔记--带有动态空间申请的类成员变量的类的运算符重载

声明代码出处:http://www.weixueyuan.net/view/6388.html 内存管理操作符new、new[]、delete和delete[]同样也可以进行操作符重载 ...

c++学习笔记--由复数类看运算符重载

#include #include using namespace std; class Complex;//前置声明 在一个需要声明未定义完成的类,比如 Complex 还未定义 之前要声明有这...

c++学习笔记 类运算符重载与友元与类型转换

有这样一个类: class Str { char str[100]; int n; public: Str(const char *pstr = "\0"){ strcpy(str, ps...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++学习-派生类的复制运算符
举报原因:
原因补充:

(最多只允许输入30个字)