【问题标题】:C++ Get class member address in constructor initialization listC++在构造函数初始化列表中获取类成员地址
【发布时间】:2016-02-03 20:19:18
【问题描述】:

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

例如:

class A
{
};

class ReferencesA
{
    A * const pA;

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

class B
{
    A a;

    ReferencesA referencesA;

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

在构造函数初始化列表中& a 是否安全?在我看来,它会是这样,但事情并不总是像我们预期的那样工作。

谢谢。

【问题讨论】:

  • 我觉得不错。可能是“referencesA”对其 ctor 内的 ptrA 所做的操作导致了崩溃,尤其是在“a”尚未构建的情况下。

标签: c++ class pointers constructor


【解决方案1】:

class B中基成员的初始化顺序是a,然后是referencesA。那是因为它们在类声明中以该顺序出现。 (它们在构造函数的初始化列表中出现的顺序(如果有的话)是不相关的。)

所以使用&a 初始化referencesA 安全的,如果有点脆弱。在您的情况下,&a 是默认构造的成员 a 的地址。

我建议不要这样编码,以防有人改变了你班级成员的顺序。

【讨论】:

  • 谢谢。问题是,如果我想要 const 指针(或引用)来指示指针在对象的整个生命周期内都是相同且有效的,那么我需要在初始化器列表中初始化东西,否则我可以' t 使用 const。
  • 值得注意的是,保存指向未初始化对象的指针是安全的,因此类中的顺序无关紧要。如果您想通过指针读取或写入a 只需在类列表中排在第一位即可。
  • @MooingDuck 你有这方面的参考吗?
  • @haelix:我不知道,但它是如此普遍,以至于您必须考虑一下才能意识到这就是我们一直在做的事情。 char buffer[30]; memset(buffer, 0, 30); 没有人会认为将指向未初始化内存的指针传递给memset 是一种未定义的行为。当您从构造函数调用成员方法时,也会这样做,因为它将隐式 this 指针传递给该方法,但尚未调用派生构造函数。哎呀,甚至int x; std::cin >> x; 传递了对未初始化内存的引用。
  • @MooingDuck 啊,好吧,我的意思是使用稍后在声明顺序中出现的成员的地址/引用来专门构造成员。我寻找了参考,但找不到任何东西(class.base.init)。鉴于this 是可访问的并且应该已经计算了偏移量,我只能认为没关系。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多