C++中的复制构造函数和基类

3
我希望能够从基类初始化派生类,如下所示:

class X {
   public:
   X() : m(3) {}
   int m;
};

class Y : public X {
   public: 
   Y() {}
   Y(const & X a)  : X(a) {}
};

这样做有什么危险或不寻常的地方吗?我需要这样做是因为我正在反序列化一堆类型未知的对象,所以我基本上想在读取整个序列化文件时使用X作为一些临时存储,然后稍后使用那些数据创建我的Y对象(和W、X、Y对象,具体取决于数据)。也许我错过了更简单的方法。

谢谢!


这在某种意义上是不寻常的,因为阅读您的类的人会问为什么在接受X的复制构造函数中,Y的成员不需要被初始化。 - Steve Guidi
我应该补充说明,Y仅存在于覆盖虚拟方法的目的;它本身没有独特的成员。 - Steve
2个回答

5
只要X有正确的拷贝构造函数(自动生成或非自动生成),并且您将Y的其他成员(如果有)设置为适当的默认值,那么这应该没有问题。
我假设Y会有一些setter方法来使用序列化流中的后续信息更新Y?
此外,请注意,您从X构造函数中创建的Y应该具有类似于以下签名的形式:
Y( X const & a)   // the X was in an invalid place before

3

这样做是否存在任何危险或异常情况?

若 Y 有其自身的数据成员(不在基类中),则它们将不会被初始化。

class Y : public X {
   public: 
   Y() {}
   Y(const X& a) : X(a)
   {
     //'n' hasn't been initialized!
   }
   int n;
};

如果Y没有自己的数据成员,为什么它是一个独立的子类?是为了覆盖X的虚拟成员吗?

如果X应该像这样被子类化,那么它应该是一个抽象类,具有纯虚拟方法,这样就不可能单独实例化。

与其您所建议的,不如考虑包含而不是子类化(Y“有一个”X而不是Y“是一个”X):

class IAnInterface
{
public:
  virtual ~IAnInterface();
  virtual void SomeMethod() = 0;
  virtual void AnotherMethod() = 0;
}

class Y : public IAnInterface {
  public: 
  Y(const X& x) : m_x(x)
  {
  }
  X m_x;
  virtual void SomeMethod() { ... an implementation ... }
  virtual void AnotherMethod() { ... another implementation ... }
};

是的,这是因为我希望Y覆盖虚方法;没有单独的数据成员。 - Steve
1
我建议(但没有明确说明原因)你在一些纯虚拟接口中声明各种虚拟方法,X 中不要有虚拟方法(而是一个 POD 纯数据类),并且让 Y 这样的叶子类继承该接口并包含(而不是从中继承)数据。 - ChrisW

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