简体   繁体   中英

Difference in calling a constructor with delegation, and in another constructor body

lets say I have a class with 2 constructors like so:

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

I know that I can call one constructor from another like Foo() : Foo(42) {} , but why shouldn't (or should) I do the following:

Foo() {
    Foo(42)
}

What is the difference in these cases? Some suggest to use an "initializer" method, called from any constructor with their respective arguments, but I am puzzled as to what happens in the case above?

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

You should not the following:

Foo() {
    Foo(42)
}

When you are in the constructor body the member variables have been just constructed. That's why in C++ initialisation list exists.

The above code is semantically wrong! You are not absolutely using delegating construction. Instead the statement Foo(42) in the body will just create another object without assigning it to any variable ( anonymous variable ).

You can imagine something like:

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

In order to use delegating constructor, you must call constructor in the initialisation list.

Foo() : Foo(42) { }

Let's put this example:

#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;
}

Output:

Constructor: 1
Destructor: 1
Msg: 1
Destructor: 1

You are destroying a second object! This is strange, what happens if we use pointers...

#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;
}

Constructor: 1
Destructor: 0xc45480
Msg: 14
Destructor: 0xc45480

Look up the pointer addr. They are the same, this means:

  • We are writing in deleted memory.
  • We are deleting the same memory twice.

These are two serious problems. You shouldn't do that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM