C++对象的构造顺序是什么

发布时间:2022-04-25 13:51:18 作者:iii
来源:亿速云 阅读:159

C++对象的构造顺序是什么

在C++编程中,对象的构造顺序是一个非常重要的概念。理解对象的构造顺序不仅有助于我们编写正确的代码,还能帮助我们避免一些潜在的错误。本文将详细探讨C++中对象的构造顺序,包括局部对象、全局对象、静态对象、成员对象以及继承关系中的对象构造顺序。

1. 局部对象的构造顺序

局部对象是指在函数内部定义的对象。局部对象的构造顺序与其定义的顺序一致。当函数被调用时,局部对象按照定义的顺序依次构造;当函数返回时,局部对象按照构造的相反顺序析构。

#include <iostream>

class A {
public:
    A() { std::cout << "A constructed\n"; }
    ~A() { std::cout << "A destructed\n"; }
};

class B {
public:
    B() { std::cout << "B constructed\n"; }
    ~B() { std::cout << "B destructed\n"; }
};

void func() {
    A a;
    B b;
}

int main() {
    func();
    return 0;
}

输出结果:

A constructed
B constructed
B destructed
A destructed

从输出结果可以看出,局部对象ab按照定义的顺序依次构造,而在函数返回时,它们按照构造的相反顺序析构。

2. 全局对象的构造顺序

全局对象是指在全局作用域中定义的对象。全局对象的构造顺序与其定义的顺序一致,但它们的构造发生在main函数执行之前。全局对象的析构顺序与构造顺序相反,析构发生在main函数返回之后。

#include <iostream>

class A {
public:
    A() { std::cout << "A constructed\n"; }
    ~A() { std::cout << "A destructed\n"; }
};

class B {
public:
    B() { std::cout << "B constructed\n"; }
    ~B() { std::cout << "B destructed\n"; }
};

A a;
B b;

int main() {
    std::cout << "main function\n";
    return 0;
}

输出结果:

A constructed
B constructed
main function
B destructed
A destructed

从输出结果可以看出,全局对象abmain函数执行之前构造,而在main函数返回之后析构。

3. 静态对象的构造顺序

静态对象包括静态局部对象和静态全局对象。静态局部对象的构造发生在第一次执行到其定义处时,而静态全局对象的构造顺序与全局对象类似,发生在main函数执行之前。静态对象的析构顺序与构造顺序相反,析构发生在main函数返回之后。

#include <iostream>

class A {
public:
    A() { std::cout << "A constructed\n"; }
    ~A() { std::cout << "A destructed\n"; }
};

class B {
public:
    B() { std::cout << "B constructed\n"; }
    ~B() { std::cout << "B destructed\n"; }
};

A a;
static B b;

void func() {
    static A a;
    static B b;
}

int main() {
    std::cout << "main function\n";
    func();
    return 0;
}

输出结果:

A constructed
B constructed
main function
A constructed
B constructed
B destructed
A destructed
B destructed
A destructed

从输出结果可以看出,静态全局对象bmain函数执行之前构造,而静态局部对象ab在第一次调用func函数时构造。所有静态对象的析构顺序与构造顺序相反,析构发生在main函数返回之后。

4. 成员对象的构造顺序

当一个类的成员是另一个类的对象时,成员对象的构造顺序与其在类中声明的顺序一致。成员对象的析构顺序与构造顺序相反。

#include <iostream>

class A {
public:
    A() { std::cout << "A constructed\n"; }
    ~A() { std::cout << "A destructed\n"; }
};

class B {
public:
    B() { std::cout << "B constructed\n"; }
    ~B() { std::cout << "B destructed\n"; }
};

class C {
    A a;
    B b;
public:
    C() { std::cout << "C constructed\n"; }
    ~C() { std::cout << "C destructed\n"; }
};

int main() {
    C c;
    return 0;
}

输出结果:

A constructed
B constructed
C constructed
C destructed
B destructed
A destructed

从输出结果可以看出,成员对象ab按照它们在类C中声明的顺序依次构造,而在类C的对象c析构时,成员对象ab按照构造的相反顺序析构。

5. 继承关系中的对象构造顺序

在继承关系中,基类对象的构造顺序与其在继承列表中的顺序一致。派生类对象的构造顺序是:先构造基类对象,再构造派生类对象。析构顺序与构造顺序相反。

#include <iostream>

class A {
public:
    A() { std::cout << "A constructed\n"; }
    ~A() { std::cout << "A destructed\n"; }
};

class B {
public:
    B() { std::cout << "B constructed\n"; }
    ~B() { std::cout << "B destructed\n"; }
};

class C : public A, public B {
public:
    C() { std::cout << "C constructed\n"; }
    ~C() { std::cout << "C destructed\n"; }
};

int main() {
    C c;
    return 0;
}

输出结果:

A constructed
B constructed
C constructed
C destructed
B destructed
A destructed

从输出结果可以看出,基类对象AB按照它们在继承列表中的顺序依次构造,而派生类对象C在基类对象构造完成之后构造。在析构时,派生类对象C先析构,然后基类对象BA按照构造的相反顺序析构。

6. 多重继承中的对象构造顺序

在多重继承中,基类对象的构造顺序与其在继承列表中的顺序一致。派生类对象的构造顺序是:先构造所有基类对象,再构造派生类对象。析构顺序与构造顺序相反。

#include <iostream>

class A {
public:
    A() { std::cout << "A constructed\n"; }
    ~A() { std::cout << "A destructed\n"; }
};

class B {
public:
    B() { std::cout << "B constructed\n"; }
    ~B() { std::cout << "B destructed\n"; }
};

class C {
public:
    C() { std::cout << "C constructed\n"; }
    ~C() { std::cout << "C destructed\n"; }
};

class D : public A, public B, public C {
public:
    D() { std::cout << "D constructed\n"; }
    ~D() { std::cout << "D destructed\n"; }
};

int main() {
    D d;
    return 0;
}

输出结果:

A constructed
B constructed
C constructed
D constructed
D destructed
C destructed
B destructed
A destructed

从输出结果可以看出,基类对象ABC按照它们在继承列表中的顺序依次构造,而派生类对象D在所有基类对象构造完成之后构造。在析构时,派生类对象D先析构,然后基类对象CBA按照构造的相反顺序析构。

7. 虚继承中的对象构造顺序

在虚继承中,虚基类对象的构造顺序与非虚基类对象不同。虚基类对象在所有非虚基类对象之前构造,且只构造一次。派生类对象的构造顺序是:先构造虚基类对象,再构造非虚基类对象,最后构造派生类对象。析构顺序与构造顺序相反。

#include <iostream>

class A {
public:
    A() { std::cout << "A constructed\n"; }
    ~A() { std::cout << "A destructed\n"; }
};

class B : virtual public A {
public:
    B() { std::cout << "B constructed\n"; }
    ~B() { std::cout << "B destructed\n"; }
};

class C : virtual public A {
public:
    C() { std::cout << "C constructed\n"; }
    ~C() { std::cout << "C destructed\n"; }
};

class D : public B, public C {
public:
    D() { std::cout << "D constructed\n"; }
    ~D() { std::cout << "D destructed\n"; }
};

int main() {
    D d;
    return 0;
}

输出结果:

A constructed
B constructed
C constructed
D constructed
D destructed
C destructed
B destructed
A destructed

从输出结果可以看出,虚基类对象A在所有非虚基类对象BC之前构造,且只构造一次。派生类对象D在虚基类对象A和非虚基类对象BC构造完成之后构造。在析构时,派生类对象D先析构,然后非虚基类对象CB析构,最后虚基类对象A析构。

8. 总结

C++中对象的构造顺序是一个复杂但非常重要的概念。理解不同情况下对象的构造顺序有助于我们编写正确的代码,并避免一些潜在的错误。以下是本文讨论的几种情况的总结:

通过理解这些构造顺序规则,我们可以更好地掌握C++中对象的生命周期管理,从而编写出更加健壮和可靠的代码。

推荐阅读:
  1. C++--对象的构造顺序与对象的销毁
  2. C++语言(03)——对象的构造

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++

上一篇:VUE怎么实现分布式医疗挂号系统预约挂号首页

下一篇:thinkphp5如何判断是否是post请求

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》