拷贝构造函数与赋值运算符重载的区别

#include<iostream> 
using namespace std;

class Test
{
public:
    Test()
    {
        ctor_count++;
        cout<<"ctor "<<endl;
    }

    Test(const Test & r)
    {
        ctor_count++;
        cout<<"copy ctor "<<endl;
    }

    Test& operator= (const Test& r)
    {
    ctor_count++;
    cout<<"assignment op "<<endl;
    return *this;

    }

private:
    static int ctor_count; //only a declaration

};

int Test::ctor_count=0; // definition + initialization

int main()

{

    Test test;
    Test test1=test;
    Test test2(test);
    Test test3=test2=test1;
    return 0;

}

以上代码运行结果为:

ctor
copy ctor
copy ctor
assignment op
copy ctor
请按任意键继续. . .

分析整个过程,Test test;调用了默认的构造函数,
Test test1=test;test1是一个新的类实例,尚未定义,此时调用拷贝构造函数;
Test test2(test);显式地调用拷贝构造函数
Test test3=test2=test1;这是一个连续的赋值,但是这里是先运算
test2=test1,两个对象均已实例化,所以这里调用的是赋值运算符。而Test test3=test2,中test3未定义,所以这里调用的是拷贝构造函数。
那么是不是拷贝构造函数未定义时对于新对象的产生,就要使用赋值运算符呢?请看下面代码:

#include<iostream> 
using namespace std;

class Test
{
public:
    Test()
    {
        ctor_count++;
        cout<<"ctor "<<endl;
    }

    //Test(const Test & r)
    //{
    //  ctor_count++;
    //  cout<<"copy ctor "<<endl;
    //}

    Test& operator= (const Test& r)
    {
    ctor_count++;
    cout<<"assignment op "<<endl;
    return *this;

    }

private:
    static int ctor_count; //only a declaration

};

int Test::ctor_count=0; // definition + initialization

int main()

{

    Test test;
    Test test1=test;
    //Test test2(test);
    Test test3=test1;
    return 0;

}

对于上面的代码我在赋值运算符中设置断点,然后调试程序,发现程序并未跳转到赋值运算符函数体内,而新类依然被定义了,这就表明对于新对象的产生,并未使用赋值运算符,那么它使用的是什么呢?
其实,虽然我们未定义拷贝构造函数,但是编译器会自动地在你需要的时候为你默认为你定义拷贝构造函数(见C++中的空类,默认产生哪些类成员函数?
我们总结起来,
复制构造函数与赋值操作符之间的区别(见百度链接
复制构造函数又称拷贝构造函数,它与赋值操作符间的区别体现在以下几个方面
1.从概念上区分:
复制构造函数是构造函数,而赋值操作符属于操作符重载范畴,它通常是类的成员函数
2.从原型上来区分:
复制构造函数原型ClassType(const ClassType &);无返回值
赋值操作符原型ClassType& operator=(const ClassType &);返回值为ClassType的引用,便于连续赋值操作
3.从使用的场合来区分:
复制构造函数用于产生对象,它用于以下几个地方:函数参数为类的值类型时、函数返回值为类类型时以及初始化语句,例如(示例了初始化语句,函数参数与函数返回值为类的值类型时较简单,这里没给出示例)
ClassType a; //
ClassType b(a); //调用复制构造函数
ClassType c = a; //调用复制构造函数
而赋值操作符要求‘=’的左右对象均已存在,它的作用就是把‘=’右边的对象的值赋给左边的对象
ClassType e;
Class Type f;
f = e; //调用赋值操作符
4.当类中含有指针成员时,两者的意义有很大区别
复制构造函数需为指针变量分配内存空间,并将实参的值拷贝到其中;而赋值操作符它实现的功能仅仅是将‘=’号右边的值拷贝至左值,在左边对象内存不足时,先释放然后再申请。当然赋值操作符必须检测是否是自身赋值,若是则直接返回当前对象的引用而不进行赋值操作。关于赋值运算符的重载写法见:面试题1:赋值运算符函数

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来回答你的问题。 首先,关于新建单文档视图的步骤,你可以按照以下步骤: 1. 打开 MFC 应用程序向导,选择“单文档”应用程序类型。 2. 在下一步中,选择“只有一个文档视图”选项,并选择一个适当的文档类型。 3. 在下一步中,选择生成的类的名称和文件名,并选择适当的选项。 4. 在最后一步中,选择“添加文件打开/保存对话框”选项,并选择适当的选项。 然后,关于读取文件 stu_ANSI.txt 并将学生列表名称显示到视图中的步骤,你可以按照以下步骤: 1. 打开文档类的源文件,在 OnOpenDocument 函数中添加文件读取代码。 2. 在读取文件时,将学生列表名称保存到文档类的一个成员变量中。 3. 打开视图类的源文件,在 OnDraw 函数中绘制学生列表名称。 最后,关于标出红框显示选中行的步骤,你可以按照以下步骤: 1. 在视图类的源文件中,添加成员变量来保存选中行的索引。 2. 在 OnLButtonDown 函数中,获取鼠标位置并计算出选中行的索引。 3. 在 OnDraw 函数中,根据选中行的索引绘制一个红色的框。 关于 CStuInfo 类的实现,你可以按照以下方式实现拷贝构造函数赋值运算符: ```c++ class CStuInfo { public: // 默认构造函数 CStuInfo() { // 初始化成员变量 } // 拷贝构造函数 CStuInfo(const CStuInfo& other) { // 复制 other 中的成员变量到当前对象中 } // 赋值运算符重载 CStuInfo& operator=(const CStuInfo& other) { if (this != &other) { // 复制 other 中的成员变量到当前对象中 } return *this; } private: // 成员变量 }; ``` 希望这些步骤可以帮助你完成你的项目。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值