首页 > 解决方案 > 以类对象为成员的类成员初始化顺序

问题描述

我试图了解成员类初始化顺序,但有一件事让我感到困惑。

#include <iostream> 

class Foo {
        int y{7};
    public:
        Foo() 
        { 
            std::cout << "Foo Constructor"; 
        }

        explicit Foo(int yy) : y(yy) 
        { 
            std::cout << "Foo " << y << std::endl; 
        }

        int gety() 
        { 
            std::cout << "Foo::gety() returning "; 
            return y; 
        }
};

class Bar {
        int x;
    public:
        Bar() 
        { 
            std::cout << "Bar constructor" << std::endl; 
        }
        explicit Bar(int xx) : x(xx) 
        { 
            std::cout << "Bar "<< x << std::endl; 
        }

        int getx() 
        { 
            std::cout << "Bar::getx() returning "; 
            return x; 
        }
};

class Class {
    Bar bar;
    Foo foo;

    public:
        Class() : bar(foo.gety()), foo(5) 
        { 
            std::cout << "Class()\n";
        }
        void printxy() 
        { 
            std::cout << "Bar.x = " << bar.getx() << " \n" << "Foo.y = " <<  foo.gety() << std::endl; 
        }
};

int main(void)
{
    Class k;
    k.printxy();
    return 0;

}

我正在用 gcc 编译这段代码--std=c++11 -Wuninitialized -Wall -pedantic

在 Class 对象中有 Foo 和 Bar 类的两个成员。在初始化列表中,我bar使用以 int 作为参数的构造函数来构造第一个对象。但据我所知, foo 尚未构造,因为它在初始化列表中排名第二。foo.gety()那么在构建之前使用时我如何不会得到任何错误呢?

我认为 C++ 可以保证构造任何使用过的对象。那么什么时候Foo构造对象呢?或者这是未定义的行为?

这是 coliru 示例的链接:Link

标签: c++c++11

解决方案


成员变量按照它们在类中定义的顺序进行初始化。在您的情况下bar将在之前初始化foo(即使您更改了构造函数初始化列表中的顺序)。

你在做什么,使用未初始化的foo对象,将导致未定义的行为。无法保证编译器能够捕获甚至报告它。


推荐阅读