简体   繁体   English

构造函数调用顺序

[英]Constructer Calling order

I know when a constructer is being called, then it gets created in the memory, and when it gets out of the block it gets destroyed unless it's static.我知道何时调用构造函数,然后在 memory 中创建它,当它离开块时它被销毁,除非它是 static。

Know I have this code:知道我有这段代码:

#include <iostream>
#include <string>
using namespace std;


class CreateSample
{
private:
    int id;
public:
    CreateSample(int i)
    {
        id = i;
        cout << "Object " << id << " is created" << endl;
    }

    ~CreateSample()
    {
        cout << "Object " << id << " is destroyed" << endl;
}
};


void fuct()
{
    CreateSample o1(1);
    static CreateSample o2(2);
}

CreateSample o3(3);
void fuct2(CreateSample o);

int main()
{
    fuct();
    static CreateSample o4(4);
    CreateSample o5(5);
    fuct2(o5);
    return 0;
}

void fuct2(CreateSample o)
{
    CreateSample o6 = o;
}

and my concern is in object o5 , why it's getting called once and gets destroyed 3 times?我担心的是 object o5 ,为什么它被调用一次并被销毁 3 次?

When you wrote fuct2(o5);当你写fuct2(o5); you're calling the function fuct2 and passing the argument by value .您正在调用 function fuct2并按传递参数。 This means a copy of the argument will be passed to the function using the implicitly defined copy constructor .这意味着参数的副本将使用隐式定义的复制构造函数传递给 function。 Thus you get the 2nd destructor call corresponding this object o .因此,您得到对应于此 object o的第二个析构函数调用。

Moreover, in fuct2 you have CreateSample o6 = o;此外,在fuct2中你有CreateSample o6 = o; which will also use the implicitly defined copy constructor to create o6 .这也将使用隐式定义的复制构造函数来创建o6 Thus you will get a third call to the destructor corresponding to this o6 .因此,您将第三次调用与此o6对应的析构函数。


You can confirm this for yourself by adding a copy ctor as shown below:您可以通过添加一个复制构造函数来自己确认这一点,如下所示:

class CreateSample
{
//other code here
public:
    
    CreateSample(const CreateSample&obj): id(obj.id)
    {
        std::cout<<"Copy ctor called"<<std::endl;
    }
};

And the output you will get is:您将获得的 output 是:

Object 5 is created            <------ctor called for o5
Copy ctor called               <------copy ctor called for parameter o
Copy ctor called               <------copy ctor called for object o6
Object 5 is destroyed          <------destructor called for o6
Object 5 is destroyed          <------destructor called for o
Object 5 is destroyed          <------destructor called for o5

Demo演示


Though in this particular example you don't strictly require a custom copy constructor or a custom copy assignment operator, they may be needed in other situations.尽管在此特定示例中您并不严格要求自定义复制构造函数或自定义复制赋值运算符,但在其他情况下可能需要它们。 Refer to the rule of three .参照三法则

CreateSample o5(5); calls the constructor CreateSample(int) .调用构造函数CreateSample(int) fuct2(o5); and CreateSample o6 = o;CreateSample o6 = o; call the implicitly-defined default copy constructor CreateSample(CreateSample const&) .调用隐式定义的默认复制构造函数CreateSample(CreateSample const&) All three of these variables ( o6 , o , and o5 ) call the destructor ~CreateSample() when their scope is exited.所有这三个变量( o6oo5 )在它们的 scope 退出时调用析构函数~CreateSample()

The fix is to follow the rule of three and also define a copy constructor and copy-assignment operator :解决方法是遵循三个规则,同时定义一个复制构造函数和复制赋值运算符

class CreateSample
{
// ...
    CreateSample(CreateSample const& o) {
        id = o.id;
        cout << "Object " << id << " is copy-constructed" << endl;
    }
    
    CreateSample& operator=(CreateSample const& o) {
        cout << "Object " << id << " is copy-assigned from " << o.id << endl;
        id = o.id;
        return *this;
    }
}

Demo on Compiler Explorer编译器资源管理器上的演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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