调用具有委托的构造函数和另一个构造函数体

时间:2017-04-09 13:49:55

标签: c++ constructor

假设我有一个包含2个构造函数的类,如下所示:

class Foo 
{
    Foo(int x);
    Foo();
    ...
}

我知道我可以像Foo() : Foo(42) {}那样调用另一个构造函数,但为什么不应该(或应该)执行以下操作:

Foo() {
    Foo(42)
}

这些案件有何不同? 有人建议使用“初始化器”方法,从任何带有各自参数的构造函数调用,但我对上面的情况会发生什么感到困惑?

3 个答案:

答案 0 :(得分:1)

表达式Foo(){Foo(42);}构造匿名临时对象,无论如何都会立即销毁,而不会更改正在构造的对象,而Foo() : Foo(42){}将初始化正在构造的对象。

答案 1 :(得分:1)

不应该以下内容:

Foo() {
    Foo(42)
}

当你在构造函数体中时,刚刚构造了成员变量。这就是为什么在C ++中初始化列表存在。

以上代码语义错误!你并非绝对使用 委托建设。相反,正文中的语句Foo(42)将只创建另一个对象而不将其分配给任何变量(匿名变量)。

您可以想象:

Foo() {
  Foo another_obj = Foo(42);
}

为了使用委托构造函数,必须调用构造函数 在初始化列表中。

Foo() : Foo(42) { }

答案 2 :(得分:1)

让我们举个例子:

#include <iostream>

class B
{
private:
    int number;
public:
    B()
    {
        B(1);
    }

    B(int x) : number(x)
    {
        std::cout << "Constructor: " << x << std::endl;
    }

    void print(){
        std::cout << "Msg: " << number << std::endl;
    }

    ~B(){std::cout << "Destructor: " << number << std::endl;}
};


int main() {
    B b;
    b.print();
    return 0;
}

输出:

  

构造函数:1
  析构函数:1
  消息:1   析构函数:1

你正在摧毁第二个物体!这很奇怪,如果我们使用指针会发生什么......

#include <iostream>

class B
{
private:
    int* arr;
public:
    B()
    {
        B(1);
    }

    B(int x)
    {
        std::cout << "Constructor: " << x << std::endl;
        arr = new int[x];
    }

    void print(int n){
        std::cout << "Msg: " << arr[n] << std::endl;
    }

    void set(int n,int val){
        arr[n] = val;
    }

    ~B()
    {
        std::cout << "Destructor: " << arr << std::endl;
        delete[] arr;
    }
};


int main() {
    B b;
    b.set(0,14);
    b.print(0);
    return 0;
}
  

构造函数:1
  析构函数:0xc45480
  消息:14
  析构函数:0xc45480

查找指针地址。它们是相同的,这意味着:

  • 我们正在写入已删除的内存。
  • 我们两次删除相同的内存。

这是两个严重的问题。你不应该这样做。