【问题标题】:C++ Copy Constructor invocationC++ 复制构造函数调用
【发布时间】:2011-07-17 21:13:59
【问题描述】:

快速提问。如果我有一个数组并且正确地重载了​​赋值运算符,那么当我做这样的事情时:

A = B 

当 A 和 B 都是数组类型的对象时,我是调用复制构造函数,还是只调用重载的赋值运算符 (=)?

我知道当复制构造函数被调用时

  1. 按值传递
  2. 返回一个类类型的值
  3. 当一个对象被括号中给出的相同类型的另一个对象声明和初始化时。

上面的3让我很困惑,认为A = B也在调用复制构造函数。

只是调用了重载的赋值运算符吗?

谢谢!

【问题讨论】:

    标签: c++ copy-constructor


    【解决方案1】:

    如果执行A=B;,则调用重载赋值运算符

    class userDefinedArray
    {
        int size ;
        int* ptr;
    
        public:
        userDefinedArray( int size ) :   size(size)
                                       , ptr( new int[size] )
        {}
        // The Big Three = 1. Copy Constructor 2. Assignment Operator 3. Destructor
    };
    

    如果上面是类定义,则应该调用赋值运算符。

    【讨论】:

    • 我知道调用了赋值运算符我只是想知道是否也调用了复制构造函数。谢谢你们俩
    【解决方案2】:

    以上都不是:你不能分配数组。


    如果你有自己的数组类,它有这样的东西:

    struct arr
    {
        arr& operator=(const arr& other)
        {
            // ...
        }
    };
    
    arr a, b;
    

    那么这些是等价的:

    a = b;
    a.operator=(b);
    

    这就像调用一个函数。

    【讨论】:

    • 在我的家庭作业中,我们创建了自己的数组类,抱歉我应该这么说。这是一个用户定义的数组类
    • 无论哪种方式,假设它不是数组,它是不同类型的对象,它是复制构造函数还是重载的赋值运算符?
    • @Rhinoo:如果你在声明时赋值,即初始化,那么它是一个复制构造函数,在其他地方它是一个赋值运算符。此外,我认为您可以使用优化将第一个案例设为赋值运算符(但我从未尝试过这样做)。
    【解决方案3】:

    既然你说数组是你自己的类,并且有一个重载的赋值运算符,那么你已经回答了你自己的问题。

    复制构造函数实际上只在你从另一个对象构造对象时被调用:

    对象一个; 对象 b(a);

    如果你这样做,它可能会被某种编译器魔法调用:

    对象一个; 对象 b = a;

    但我从来没有费心去查。

    如果你只是做 a = b 你没有构造 a,因此你不会调用复制构造函数。

    有意义吗?

    【讨论】:

    • 如果有疑问,请在复制构造函数和赋值运算符中添加一些跟踪,然后运行代码。你很快就会看到发生了什么。
    • 是的,我已经阅读课本将近 14 个小时了。我得到了一个我很好理解的点,但我现在已经过了那个点,我很累,开始迷惑自己。我要去睡觉了哈哈..谢谢大家!
    【解决方案4】:

    复制构造函数被调用 - 正如你所说 - 什么时候

    1. 按值传递
    2. 返回一个类类型的值
    3. 当一个对象被括号中给出的相同类型的另一个对象声明和初始化时或作为赋值。

    考虑以下代码的输出:

    #include <iostream>
    
    using std::cout;
    
    class Test
    {
    public:
        Test()
        {
        }
        Test(const Test& T)
        {
            cout << "Calling Copy Constructor";
        }
    };
    
    void PassingValue(Test T)
    {
        cout << " while Passing parameter by value\n\n";
    }
    
    void PassingReference(Test &T)
    {
        cout << "NOT CALLING copy constructor while Passsing Parameter by reference\n\n";
    }
    
    int main()
    {
        Test One;
        // case 1 :
        cout << "case 1 : \n";
        Test Two(One);
        cout << " while creating Two as a copy of One\n\n";
        // case 2 :
        cout << "case 2 : \n";
        PassingValue(One);
        // case 3 :
        cout << "case 3 : \n";
        Test Three = Two;
        cout << " while assigning initial value\n\n";
        // case 4 :
        cout << "case 4 : \n";
        PassingReference(Two);
        // case 5
        cout << "case 5 : \n";
        Test Four;
        Four = Three;
        cout << "NOT CALLING copy constructor while assigning normally\n\n";
        return 0;
    }
    

    【讨论】:

      【解决方案5】:

      上面的3让我很困惑,认为A = B也在调用复制构造函数。

      除非您的复制构造函数声明为explicit,否则以下内容确实会调用复制构造函数:

      MyType A = B; // will call copy ctor
      

      我相信标准保证了这一点(我手头没有我的参考资料),所以你知道你不会调用默认 ctor 后跟赋值运算符。

      【讨论】:

        猜你喜欢
        • 2018-10-17
        • 2013-04-17
        • 1970-01-01
        • 2016-03-25
        • 2022-11-21
        • 1970-01-01
        • 2012-09-20
        • 2016-03-05
        相关资源
        最近更新 更多