【问题标题】:Is the following safe to do?以下操作安全吗?
【发布时间】:2012-01-30 23:41:49
【问题描述】:

考虑这段代码:

struct A {};

struct B
{
    B(A* a) : a(a) {}
private:
    A* a;
};

struct base
{
    base(B b) : b(b) {}
protected:
    A a;
private:
    B b;
};

struct derived : public base
{
    derived() : base(B(&a)) // <-- IS THIS OK?
    {}
};

这里,基类需要一个B对象,由派生类传递给它的构造函数,B对象引用了一个A对象,但是A对象存在于基类内部。

B 对象的构造函数除了存储它之外对 A 指针没有做任何事情,所以我认为这应该没问题,但仍然感觉不对,因为从技术上讲,A 对象在我当时还不存在'将其传递给基础构造函数。

我这样做会不会遇到麻烦,还是应该这样?

【问题讨论】:

  • 安全,只要“a”(如您所标记的)是“结构派生”的成员 - 确保“a”存在结构派生的对象
  • 不要使用这样冲突的变量名,否则这段代码的维护者会受到伤害。
  • 一开始我想说类型不匹配,但我记得隐式构造。 explicit 关键字应该是隐含的,由 implicit 关键字代替。
  • @BenVoigt:哪里有冲突的变量名?
  • @trinithis:隐式构造发生在哪里?

标签: c++ inheritance undefined-behavior


【解决方案1】:

只要您不在B 的构造函数中使用 a 是安全的,因为对象a 尚未构造。

我的意思是,您不应该在 B's 构造函数中取消引用指针 a;但是在base的构造函数执行后,你可以安全地在B的其他方法中解引用B::a

【讨论】:

  • 你的意思是,只要我不在B构造函数中使用a。在B 的其他地方使用a 应该没问题吧?
  • @HighCommander4:是的。我就是这么写的。在B构造函数执行后,你可以放心地在B的其他方法中使用a
  • @HighCommander4:或者B的析构函数,因为临时的B变量会在a被构造之前被销毁。
  • @Nawaz 我认为应该是:“bases 构造函数执行后,您可以安全地在B 的其他方法中使用B::a。”
  • @Nawaz:我不确定我是否这样做 - 我希望他实际上并没有试图利用这些......
【解决方案2】:

a 还没有被构造,但是它确实有一个地址,此时取它的地址是合法的。不过,您确实需要确保不要在 B 的构造函数中使用指针(即不要取消引用指针)。

不过,这一切都相当尴尬。

【讨论】:

  • 如果我使用引用而不是指针,这会改变吗?
猜你喜欢
  • 2011-06-19
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 2011-02-13
相关资源
最近更新 更多