Копировать конструкторы и базовые классы C ++ - PullRequest
3 голосов
/ 30 сентября 2009

Я хотел бы иметь возможность инициализировать производный класс из базового класса, например:

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 objs, в зависимости от данных) с последующим использованием этих данных. Может быть, я упускаю более простой способ.

Спасибо!

Ответы [ 2 ]

5 голосов
/ 30 сентября 2009

С этим не должно быть проблем, если X имеет правильный ctor для копирования (автоматически сгенерированный или нет), а для других элементов Y (если есть) установлены соответствующие значения по умолчанию.

Я предполагаю, что Y будет иметь некоторые методы установки для обновления Y с результатами последующей информации из потока сериализации?

Также обратите внимание, что ваш Y из конструктора X должен иметь подпись, которая выглядит примерно так:

Y( X const & a)   // the X was in an invalid place before
3 голосов
/ 30 сентября 2009

Есть ли что-нибудь опасное или необычное в этом?

Если у 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 ... }
};
...