Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

函数内、块内、全局变量创建和析构顺序 #45

Open
Ksitta opened this issue Apr 24, 2021 · 0 comments
Open

函数内、块内、全局变量创建和析构顺序 #45

Ksitta opened this issue Apr 24, 2021 · 0 comments

Comments

@Ksitta
Copy link

Ksitta commented Apr 24, 2021

函数内、块内、全局变量创建和析构顺序

这次作业的第二题中涉及到了一些对象创建和销毁的顺序、时间相关的问题这里做一个简单的整理。

1、全局变量最先创建最后销毁

2、在同一个块内,先创建的后销毁

3、局部变量(非static变量,非new产生的对象),在一个块内的变量,在块结束后将会被销毁

例如,在如下块内,有a1,a2两个对象,则a1会先创建,而a2后创建,块结束后,a2先销毁,a1后销毁。

{
	Test a1;
	Test a2;
}

4、在带参数的函数中,参数会在进入前创建(先于函数体内对象),会在结束后销毁(晚于函数体内对象)

5、由于函数返回值是对象而在return时也会产生一次对象构造(通常会被编译器优化,但是可以通过开启编译指令-fno-elide-constructors让编译器不优化),这个临时对象会在return语句执行时创建,然后return语句结束后,函数体内的对象被析构,然后这个临时变量被析构。最后才到作为参数的变量被析构。

如下面例子:

Test f(Test a){
    cout << "------ entering f() ------" << endl;
    Test b;
    Test c;
    cout << "------ exiting f() ------" << endl;
    return b;
}

对象的创建和析构顺序如下

a -> b -> c -> t(临时变量) -> ~c -> ~b -> ~t -> ~a

6、对于被当作参数的临时变量来说,会在函数调用结束后被析构

下列示例:

Test f(Test a){
    cout << "------ entering f() ------" << endl;
    Test b;
    Test c;
    cout << "------ exiting f() ------" << endl;
    return b;
}

int main(){
	Test k1;
    Test k2 = f(Test(k1));
    return 0;
}

f(Test(k1));此处会先调用拷贝构造函数创建一个临时变量t1,而函数形参为a,此处t1会先于a构造,晚于a析构

可以看一个较为完整的例子:

注:编译开启-fno-elide-constructors选项

#include <iostream>

using namespace std;

class Test{
private:
    int id;
    int copy;
public:
    static int count;
    Test(){
        this->copy = 0;
        count++;
        this->id = count;
        cout << id <<" is created" << endl;
    }
    Test(const Test & a){
        this->id = a.id;
        this->copy = a.copy + 1;
        cout << id << " copyed version " << copy << " is created" << endl;
    }
    ~Test(){
        cout << id;
        if(this->copy){
            cout << " copyed version " << copy;
        }
        cout <<" is destoryed" << endl;
    }
};

int Test::count = 0;

Test g1;
Test g2;

Test f(Test a){
    cout << "------ entering f() ------" << endl;
    Test b;
    Test c;
    cout << "------ exiting f() ------" << endl;
    return b;
}

int main(){
    cout << "------ entering main() ------" << endl;
    Test k1;
    Test k2 = f(Test(k1));
    cout << "------ exiting main() ------" << endl;
    return 0;
}

执行结果如下:

1 is created
2 is created
------ entering main() ------
3 is created
3 copyed version 1 is created
3 copyed version 2 is created
------ entering f() ------
4 is created
5 is created
------ exiting f() ------
4 copyed version 1 is created
5 is destoryed
4 is destoryed
4 copyed version 2 is created
4 copyed version 1 is destoryed
3 copyed version 2 is destoryed
3 copyed version 1 is destoryed
------ exiting main() ------
4 copyed version 2 is destoryed
3 is destoryed
2 is destoryed
1 is destoryed

可以较为完整的判断上述每个对象被创建和析构的时机

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant