c++ - 使用匿名对象时,默认构造函数和复制构造函数都不会被调用

标签 c++ copy-constructor default-constructor move-constructor most-vexing-parse

下面是旨在测试构造函数的代码片段。它是在 VS 2015 中运行的。

在我看来,“B b(B())”与“B b = B()”具有相同的功能,但是,我的代码似乎表明它们的行为不同。

我知道编译器优化存在复制省略,但我认为至少在执行“B b(B())”时应该调用默认构造函数。 谁能帮我指出我的误解在哪里?

class B
{
public:
    B() {
        ++i;
        x = new int[100];
        cout << "default constructor!"<<" "<<i << endl;
        cout << "x address:" << x << endl << "--------" << endl;
    }
    B(const B &b)  //copy constructor
    {   
        ++i;
        cout << "Copy constructor & called " << i<< endl 
            << "--------" << endl;
    }
    B(B &&b)//move constructor
    {
        x = b.x;    
        ++i;
        b.x = nullptr;
        cout << "Copy constructor && called" << i << endl 
            <<"x address:"<< x << endl << "--------" << endl;

    }
    void print()
    {
        cout << "b address:" << x << endl << "--------" << endl;
    }
private:
    static int i;
    int *x;
};
int B::i = 0;


int main()
{
    B b1; //default constructor
    b1.print();
    B b2 = B(); //default constructor only
    b2.print();
    B b3(B());  //????nothing called... why???
    B b4 = b2; //copy constructor
    B b5 = move(b2); //move constructor
    b2.print();

    return 0;
}

enter image description here

最佳答案

请注意,B b(B()) 是函数声明,根本不是变量定义,因此不会调用构造函数。

根据Most vexing parse , B b(B()) 是一个函数声明,名为 b 的函数返回一个 B 类型的对象,并且有一个(未命名)参数是一个指向返回类型 B 且不带参数的函数的指针。

您可以使用大括号 ( list initlization (C++11 起)) 来解决这个问题,例如

B b1( B{} );
B b2{ B() };
B b3{ B{} };  // preferable from C++11

关于c++ - 使用匿名对象时,默认构造函数和复制构造函数都不会被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40098711/

相关文章:

class - 具有成员 std::mutex(或其他不可复制对象)的类的复制或移动构造函数?

c++ - 构造函数格式错误和隐式删除

c++ - 是否有可能制作一个模仿基本类型的构造函数语义的 C++ 类型?

C++ 默认构造函数不可用

c++ - C++ 中 ubuntu 中的密码屏蔽

c++ - 为什么复制赋值运算符必须返回引用/常量引用?

java - 如何在构造函数数组中查找复制构造函数

python - 如何将用 C++ 编写的函数 ("noblock") 导入 GRC

c++ - 关于视频游戏编程,你有什么好的书名可以给我吗?

c++ - 如何在 Go 中使用 C++