【问题标题】:Neither Default Constructor nor Copy Constructor is called when using anonymous object使用匿名对象时,既不调用默认构造函数,也不调用复制构造函数
【发布时间】:2017-02-27 03:57:14
【问题描述】:

下面是用于测试构造函数的 sn-p。它在 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;
}

【问题讨论】:

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


    【解决方案1】:

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

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

    你可以通过使用大括号(list initlization(C++11 起))来解决它,比如

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

    【讨论】:

    • 不错的收获! @Shirley Feng,根据维基文章,您可以通过在您的内部 ctor 调用周围添加括号来获得预期的行为。示例:B b3( (B()) );
    • 谢谢分享!!它救了我XD
    • 只是想知道,继续使用一种初始化约定不是更好吗?即B b{ B{} }; 而不是
    • @AdrianShum 你是对的。我只想指出,只使用一对大括号就可以解决这里的歧义。
    • @ShirleyFeng 是的!这是一个非常重要的 C++11 特性。
    猜你喜欢
    • 2017-07-28
    • 2016-03-25
    • 1970-01-01
    • 2017-02-08
    • 2013-03-13
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多