【问题标题】:When is a c++ constructor not called?什么时候不调用 c++ 构造函数?
【发布时间】:2013-06-21 16:03:37
【问题描述】:

我有一种情况,似乎没有调用构造函数:

#include <iostream>

using namespace std;

int main ()
{
    class yoyo
    {
        public:
        int i;
        yoyo()
        {
            i = 0;
            cout << "defaultly initialized to 0" << endl;
        }
        yoyo (int j) : i(j)
        {
            cout << "initialized to " << j << endl;
        }
    };

    int i;

    yoyo a;
    cout << "Hello1, i: " << a.i << endl;

    yoyo b(5);
    cout << "Hello2, i: " << b.i << endl;

    yoyo c = b;                                   /* 1 */
    cout << "Hello3, i: " << c.i << endl;

    return 0;
}

输出是:

defaultly initialized to 0
Hello1, i: 0
initialized to 5
Hello2, i: 5
Hello3, i: 5

(注意:Hello2 和 Hello3 之间没有任何关系)

如果我将程序更改为如下所示:

#include <iostream>

using namespace std;

int main ()
{
    class yoyo
    {
        public:
        int i;
        yoyo()
        {
            i = 0;
            cout << "defaultly initialized to 0" << endl;
        }
        yoyo (int j) : i(j)
        {
            cout << "initialized to " << j << endl;
        }
    };

    int i;

    yoyo a;
    cout << "Hello1, i: " << a.i << endl;

    yoyo b(5);
    cout << "Hello2, i: " << b.i << endl;

    yoyo c; c = b;                                  /* 1 */
    cout << "Hello3, i: " << c.i << endl;

    return 0;
}

(唯一的区别在于 /* 1 */ 标记的行)

现在的输出是:

defaultly initialized to 0
Hello1, i: 0
initialized to 5
Hello2, i: 5
defaultly initialized to 0
Hello3, i: 5

现在在 Hello2 和 Hello3 之间有一个构造函数调用。我的问题是,为什么在第一种情况下没有(可见的)构造函数调用?

【问题讨论】:

  • 您一直缺少跟踪默认复制构造函数和operator=() 实现。

标签: c++ constructor explicit-constructor


【解决方案1】:

如果是

yoyo c = b;

调用的是copy constructor

而在

的情况下
yoyo c; c = b;

调用的是 copy assignment 运算符。

如果您不提供其中任何一个,编译器将为您生成默认版本。


如果您想创建自己的复制构造函数,它可能如下所示:

yoyo(const yoyo& other)
    : i(other.i)
    { std::cout << "copy constructor initialized\n"; }

复制赋值运算符如下所示:

yoyo& operator=(const yoyo& other)
    {
        i = other.i;
        return *this;
    }

他们都定义了内部当然是类定义。

【讨论】:

    【解决方案2】:

    第一种情况:

    yoyo c = b;   
    

    调用copy constructor,在这种情况下编译器会为您隐式生成。

    【讨论】:

      【解决方案3】:
       yoyo c = b; 
      

      这称为复制初始化;编译器生成的复制构造函数将被调用,c 将使用该副本初始化。此外,c 的默认构造函数也会被调用。

      c = b;
      

      这里,这不是初始化,这是赋值。编译器生成的赋值运算符将在该行被调用。

      【讨论】:

        【解决方案4】:

        在您的代码中,

        yoyo c=b 将调用复制构造函数。如果你想看到它被调用,你必须明确定义它。

        例如:

        yoyo(const yoyo& obj)
        {
           this->i=obj.i;  cout<<"copy constructor"<<endl;
        }
        

        在第二种情况下,它将调用构造函数,然后调用赋值运算符

        yoyo c; //constructor
        c = b;  //assignment operator for which only copying occurs
        

        你可以像下面这样重载赋值运算符

        yoyo& operator=(yoyo& obj)
        {
            i = obj.i;
            cout << "assignment operator" << endl;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-29
          • 1970-01-01
          • 2021-12-12
          • 2019-10-16
          相关资源
          最近更新 更多