我有一个类将一个数据成员的地址传递给另一个数据成员的构造函数:
class MemberA {
public:
MemberA(MemberB* ptr) : ptr_(ptr) {}
private:
MemberB* ptr_;
};
struct MemberB {
public:
MemberB(int x) : x_(x) {}
private:
int x_;
};
class Foo {
public:
Foo() : a(&b), b(1) {}
private:
MemberA a;
MemberB b;
};
在本例中,a
在 b
之前构造,但取决于 b
的地址。这行得通吗?我的直觉是数据成员是在开始时分配的,因此 Foo
知道它需要多大,也因为它们是在堆栈上分配的。但是,我不知道这是一个事实,想验证一下。
顺便说一句,我知道翻转订单可以完全解决这个问题;如果 b
在 a
之前声明和初始化,那么我知道它会起作用。我也意识到即使地址是已知的,在初始化之前取消引用 b_
也是未定义的行为。但是,我真的只是好奇上述情况是否合法
谢谢!
答案 0 :(得分:1)
数据成员在对象本身内分配。标准中没有指定大部分内容,但大多数编译器都是这样做的:
-- FOO --------------------------------------------
| --MemberA--- --MemberB--- |
| | | | | other stuff follows |
| ------------ ------------ |
---------------------------------------------------
所以,当 Foo F;
被构造时,在它的 b
被初始化之前,它的地址相对于 Foo F
已经是已知的。所以b
的地址可以传递给a
的构造函数。但是,如果 a
在其构造期间访问此地址,则会发生未定义的行为。但只是存储地址供以后使用?那行得通。