当我分配该类的两个对象时,为什么调用我的构造函数

Why is my constructor being called when I assign two objects of that class?

本文关键字:对象 两个 为什么 构造函数 我的 调用 分配      更新时间:2023-10-16

我很困惑,如果这很明显,我很抱歉。我在以下方面错了吗:

 struct MyStruct
    {
       MyStruct(){};
       MyStruct(MyStruct* arg){};
    }

MyStruct(MyStruct*arg({};构造函数是否将指向MyStruct的一个指针作为参数?

因为我有一个问题,当我这样做的时候,这个构造函数(我认为是(被调用了:

int main()
{
   MyStruct obj;
   MyStruct* objPtr;
   obj = objPtr;
   return 0;
} 

当将obj分配给objPtr时,我希望编译器会抱怨,但它没有,而是调用MyStruct(MyStruct*arg(;我认为这是一个接受指针参数的构造函数。

如有任何帮助,我们将不胜感激。此外,如果我在类中添加一个复制赋值运算符,它仍然会发生。

编辑:谢谢你的回答。我似乎有一些关于这方面的阅读,主题似乎是(对于任何想知道的人来说(在C++中转换构造函数。此外,我还在猜测明确的关键词。这里有一个SO问题的链接,可以解释它:

C++中的转换构造函数是什么?它是干什么的?

  1. 编译器为您合成一个赋值运算符:

    MyStruct& MyStruct::operator=(MyStruct const&) = default;
    
  2. 当它看到赋值时,它会为操作符找到一个候选者(即它创建的操作符(。然后它看到它可以使用您的构造函数进行转换,转换为允许赋值的类型(MyStruct(。所以它可以归结为:

    obj = MyStruct (objPtr);
    

如果您希望看到错误发生,请将您的构造函数标记为显式:

struct MyStruct
{
   MyStruct(){};
   explicit MyStruct(MyStruct* arg){};
}

对于obj = objPtr;,编译器将尝试使用参数objPtr(即MyStruct*(在obj上调用MyStruct::operator=()。有一个候选者,即隐式声明的复制赋值运算符MyStruct::operator=(const MyStruct&)MyStruct可以通过转换器构造函数MyStruct::MyStruct(MyStruct*)MyStruct*转换而来,因此它进行编译。

如果将MyStruct::MyStruct(MyStruct*)设置为explicit,则编译将失败。

struct MyStruct
{
   MyStruct(){};
   explicit MyStruct(MyStruct* arg){};
};

当您将objPtr分配给obj时,您将为MyStruct分配类型为MyStruct*的值,这是无效的。但是,由于您有一个采用MyStruct*的构造函数,因此会调用它来转换值。它基本上是一个隐式转换:(

obj = objPtr;

将调用

obj.MyStruct::operator =(MyStruct(objPtr));

将构造函数标记为explicit,以避免这种不需要的转换。

相关文章: