C++在构造函数初始化列表中获取类成员地址

3

我遇到了内存违规错误,但我不知道它的来源。 我的问题是:在构造函数初始化列表中,我是否可以获得类成员的地址,以便将其传递给需要引用它的对象?

例如:

class A
{
};

class ReferencesA
{
    A * const pA;

    ReferencesA( A * ptrA ) : pA( ptrA ) { }
};

class B
{
    A a;

    ReferencesA referencesA;

    B() : referencesA( & a ) { }
};

在构造函数初始化列表中使用& a是安全的吗?我觉得应该是安全的,但事情并不总是如我们所期望的那样。

谢谢。


看起来还不错。可能是“referencesA”在其构造函数中对ptrA的操作导致了崩溃,特别是如果“a”尚未构造完成。 - rakeshdn
1个回答

2
< p > 在类B中,基本成员的初始化顺序是a,然后是referencesA。这是因为它们在类声明中以这个顺序出现。(在构造函数的初始化列表中出现的顺序(如果有)并不重要。)< /p > < p > 因此,使用&a来初始化referencesA是安全的,但有点脆弱。在您的情况下,&a是默认构造的成员a的地址。< /p > < p > 我建议不要这样编码,以防别人更改您的类中的成员顺序。< /p >

2
谢谢。问题在于,如果我想要有const指针(或引用)来表示指针将在整个对象的生命周期内保持相同和有效,那么我需要在初始化列表中初始化事物,否则我无法使用const。 - Virus721
5
值得注意的是,保存一个指向未初始化对象的指针是安全的,因此类中的顺序并不重要。如果你想通过指针进行读取或写入操作,那么只有当a在类列表中排在第一位时才需要这样做。 - Mooing Duck
1
@MooingDuck 你有相关的参考资料吗? - haelix
1
@haelix:我不这么认为,但这种做法是如此普遍,以至于你甚至需要思考才能意识到我们一直在这样做。char buffer[30]; memset(buffer, 0, 30); 没有人会争辩将指向未初始化内存的指针传递给 memset 是未定义行为。当您从构造函数调用成员方法时,它也会这样做,因为它将一个隐式的 this 指针传递给方法,但派生构造函数尚未被调用。甚至 int x; std::cin >> x; 也会传递对未初始化内存的引用。 - Mooing Duck
1
@MooingDuck 噢,我指的是特别是使用稍后在声明顺序中出现的成员的地址/引用构造成员。我查找了参考资料,但没有找到任何东西(class.base.init)。我只能想到这是可以的,因为this是可访问的,而且偏移量应该已经计算好了。 - haelix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接