复制构造函数与赋值操作符的重载

1. 试验功能:带有指针成员且指针成员为类类型时,自定义复制构造函数与赋值操作符的行为是怎样的。

2. 试验结果:

(1)当指针成员为一般普通成员时,我们可以自己在复制构造函数中为指针分配内存并拷贝内容,在赋值操作符函数中,检查或者删除左操作数的内存,并分配新内存然后拷贝内容到新分配内存中;

(2)当指针成员为类类型(本例即是)时,称为第一级类类型的指针成员:

         在复制构造函数中:就要显式调用指针成员所属类型的复制构造函数生成一个临时对象,然后将该临时对象赋值给指针成员,可以通过两个方式进行赋值,一是:在复制构造函数的初始化式中以“指针变量(new 指针成员所属类类型复制构造函数)”的方式,二是:”指针变量=new 指针成员所属类类型复制构造函数“,本例方式为第一种方式,注意:这种方式显式调用了指针成员所属类的复制构造函数;

         在赋值操作符函数中:可以直接用”对象=对象“的形式实现赋值操作符,如本例中:*pcd = *obj.pcd; pcd就是一个类类型的指针成员,注意这种赋值就会调用指针成员所属类的赋值操作符函数;

3. 当指针成员所属的类类型又包含指针成员时,仍然遵循本实验,即在一般指针成员时可以用(1)的方式实现拷贝,指针成员又为类类型时,就按照(2)的方式为该指针成员所属类实现复制构造函数和赋值操作符;这个指针成员所属类的复制构造函数和赋值操作符函数会在第一级指针成员所属类的复制构造函数和赋值操作符函数被调用的时候分别被调用,如果类类型指针成员所属类又包含了多级类类型的指针成员,就要为其做(2)的工作。

代码:

c.h 定义类 CC

//c.h defined class CC
//
#include "d.h"

class CC
{
  public:
    CC();
    CC(int v1, int v2);
    virtual ~CC();
    CC(const CC &obj);
    CC& operator=(const CC &obj);
    int getVal() const;
    int getObjVal() const;

  private:
    int a;
    CD *pcd;
};
c.cpp

#include "iostream"
#include "c.h"

CC::CC():a(0), pcd(new CD(0))
{
  std::cout << "CC Default constructor CC();" << std::endl;
}

CC::CC(int v1, int v2):a(v1), pcd(new CD(v2))
{
  std::cout << "CC constructor CC(int v1, intv2);" << std::endl;
}

CC::CC(const CC &obj):a(obj.a), pcd(new CD(*obj.pcd))
{
  std::cout << "CC Copy constructor CC(const CC &obj);" << std::endl;
}

CC &CC::operator=(const CC &obj)
{
  std::cout << "CC assign constructor operator=(const CC &obj);" << std::endl;
  a = obj.a;
  *pcd = *obj.pcd;
}

CC::~CC()
{
  std::cout << "CC DeConstructor ~CC();" << std::endl;
  delete pcd;
}

int CC::getVal() const
{
  return a;
}

int CC::getObjVal() const
{
  return pcd->getVal();
}
d.h 定义类CD

//d.h defined class CD
//
class CD
{
  public:
    CD() {};
    CD(int v1):b(v1) {};
    virtual ~CD() {};
    CD(const CD &obj);
    CD &operator=(const CD& obj);
    int getVal() const;
  private:
    int b;
};
d.cpp

#include <iostream>
#include "d.h"
CD::CD(const CD &obj)
{
  std::cout << "CD Copy constructor CD(const CD &obj);" << std::endl;
  b = obj.b;
}

CD &CD::operator=(const CD& obj)
{
  std::cout << "CD assign constructor operator=(const CD &obj);" << std::endl;
  b = obj.b;
}

int CD::getVal() const
{
  return b;
}
main.cpp

#include <iostream>
#include "c.h"
using namespace std;

int test(CC o);
int main()
{
  CC c1(1, 10);
  CC c2(c1);
  cout << "c1.a:" << c1.getVal() << endl;
  cout << "c1.cd.b:" << c1.getObjVal() << endl;

  cout << "c2.a:" << c2.getVal() << endl;
  cout << "c2.cd.b:" << c2.getObjVal() << endl;

  cout << "test:" << test(c1) << endl;

  CC c3(3, 30);
  c3 = c2;
  cout << "c3.a:" << c3.getVal() << endl;
  cout << "c3.cd.b:" << c3.getObjVal() << endl;


/*
  CD cd1;
  CD cd2;
  cd1 = cd2;
*/

  return 0;
}

int test(CC o)
{
  return o.getObjVal();
}

---------------------------------

main 运行结果:

[root@centos cc++]# ./main
CC constructor CC(int v1, intv2);
CD Copy constructor CD(const CD &obj);
CC Copy constructor CC(const CC &obj);
c1.a:1
c1.cd.b:10
c2.a:1
c2.cd.b:10
CD Copy constructor CD(const CD &obj);
CC Copy constructor CC(const CC &obj);
test:10
CC DeConstructor ~CC();
CC constructor CC(int v1, intv2);
CC assign constructor operator=(const CC &obj); //CC包含类型为CD的指针成员pcd,当执行*pcd = *obj.pcd时,就会调用CC的赋值操作符,
CD assign constructor operator=(const CD &obj);//这时CD的赋值操作符就会被自动调用,因为这是对象赋值而不是指针赋值,指针赋值时,复制构造函数和赋值操作符就不会被自动调用,依次类推,如果CD又包含类类型的指针成员,那么我们也要为其实现复制构造函数和赋值操作符,那么他们也会被自动调用
c3.a:1
c3.cd.b:10
CC DeConstructor ~CC();
CC DeConstructor ~CC();
CC DeConstructor ~CC();


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

种菜的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值