【问题标题】:Why a constructor is called twice when an object is instantiated为什么在实例化对象时会调用两次构造函数
【发布时间】:2021-11-22 21:10:19
【问题描述】:

根据我的理解,我知道当一个对象被实例化时,一个构造函数会被调用一次。但是我不明白为什么两个构造函数都被调用并且只实例化了一个对象

#include <iostream>
using namespace std;
#define print(me) cout << me << endl;

class A 
{
    public:
    A() { print("default called"); }
    A(int x) { print("paramterized called"); }
};


int main()
{
    A a;
    a = A(10);
    return 0;
}

我得到了输出: 默认调用 参数化调用

【问题讨论】:

  • A a; 调用默认构造函数。
  • A a; 没有指定构造函数,所以调用了默认的(没有参数的)。
  • 您应该打印this 的值而不仅仅是消息。然后你会意识到构造函数是为不同的对象调用的,而不是同一个对象。但是使用不明智的print 宏,您将无法做到这一点。直接在构造函数中使用std::cout,不要用print之类的宏来混淆代码。
  • 完全按预期工作!构造函数1:A a;构造函数二 A(10);
  • 如果你提供了一个打印赋值操作符,你会看到它也被调用了

标签: c++ class oop constructor


【解决方案1】:

在这些行中

A a;
a = A(10);

创建了两个 A 类型的对象。第一个是在声明中使用默认构造函数创建的

A a;

第二个是在表达式A(10)中创建的临时对象

a = A(10);

然后使用复制赋值运算符将其分配给已经存在的对象a

由于复制省略,您可以通过最初编写来避免使用默认构造函数

A a = A( 10 );

实际上由于复制省略,它相当于

A a( 10 );

前提是复制构造函数未声明为显式。

【讨论】:

  • “假设复制构造函数未声明为显式” 我不明白为什么它应该是一个问题。我们这里不做任何隐式转换,只是调用构造函数see here
  • @Fareanor 在此声明中 A a = A( 10 );复制构造函数至少在 C++ 14 中不应是显式的。
  • 哦,对了,但是你在A a(10); 语法下面提到了它,因此我很困惑。因为没有问题,即使在C++14中使用原始语法A a(10);不管copy ctor是否为explicit(因为这里不涉及copy ctor)
  • @Vlad 来自莫斯科,谢谢老兄,但我不明白你所说的“创建了两个 A 类型的对象”是什么意思,因为我只有一个实例“a”!
  • @AccessDenied 在这个表达式 A(10) 中创建了一个 A 类型的临时对象。
【解决方案2】:

在使用 A a 创建函数时,您也在调用函数;

您可以通过在创建值时初始化值来解决它,如下所示:

int main()
{
    A a = A(10); 
} 

或者正如法瑞诺所说:

 int main()
    {
        A a(10);
    } 

【讨论】:

    猜你喜欢
    • 2013-11-05
    • 1970-01-01
    • 2013-06-08
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多