繁体   English   中英

在C ++中派生类构造函数之后调用基类构造函数

[英]Call base class constructor after the derived class constructor in C++

考虑以下情况:

#include <iostream>
using namespace std;

class A {
  public:
    int y;
    A(int &x) {
        x = 2;
        y = 1;
    }
};

class B : public A {
  public:
    int *p;
    B(int t) : A(*p) {}
};

int main() {
    B b(2);
    return 0;
}

当调用B的构造函数时, p具有垃圾值。 因此,当*p传递给A() ,它会给我一个分段错误。 我想初始化p = new int; 致电A(*p) - 这可能吗?

编辑:有趣的是,没有参数调用B的构造函数并没有给出分段错误。

这样做的方法是引入另一个结构:

class A {
  public:
    int y;
    A(int &x) {
        x = 2;
        y = 1;
    }
};

struct C
{
    explicit C(int* p) p(p) {}
    int* p;
}

class B : private C, public A {
  public:
    B(int t) : C(new int), A(*p) {}
    ~B() {delete p;}
    B(const B&) = delete;
    B& operator =(const B&) = delete;
};

我认为这是不可能的,因为在调用B()之前没有分配p。 在调用构造函数之前,它不会在initialize-list中被赋值。

B() : p(new int(10) )  // p is still a junk value here
{
   // p already has a valid value here
}

不,你不能。 订单明确定义为:

  • 首先,派生程度最高的类的构造函数调用虚拟基类子对象的构造函数。 虚拟基类以深度优先,左直接顺序初始化。
  • 接下来,直接基类子对象按照它们在类定义中声明的顺序构造。
  • 接下来,(非静态)成员子对象按照它们在类定义中声明的顺序构造。
  • 最后,执行构造函数的主体。

如果你发现你处于某种必须做这种奇怪事情的状态,那么就该重新审视一下这个设计了。

我用另一种方式试了一下。 我不知道它是否符合您的要求,或者即使它是否正确。 但看看。

class A
{
public:
  int y;
  A() {}
  A(int &x)
  {
    x = 2;
    y = 1;
  }
};

class B : public A
{
public:
  int *p;
  B(int x)  
  {
    p = new int();
    A::A(*p);
  }
};

int _tmain(int argc, _TCHAR* argv[])
{
  B b(2);
  return 0;
}

希望它的正确和有帮助。

注意: - 对我来说,看起来不可能在基本初始化列表中传递初始化指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM