【问题标题】:Base class data member type depends on derived class基类数据成员类型取决于派生类
【发布时间】:2019-10-11 17:08:57
【问题描述】:

我有一个关于 c++ 中的多态性的问题:

头文件

class Base {
public:
  type1 data;
};

class Derived1 : public Base {
public:
  type2 data;
};

class Derived2 : public Base {
public:
  type3 data;
};

代码:

Base * obj;

if (...)
  obj = new Derived1();
else
  obj = new Dervied2();

// Do something on declared object
DoSomething( obj->data );

如果类型取决于所定义的派生类,我应该将什么作为 type1 放在基类中?函数 DoSomething() 将被重载以接受 type2 或 type3。

【问题讨论】:

  • 如果您需要以依赖于派生类的方式更改基类,那么您使用的继承不正确。如果您的设计合理,一个通常效果很好的解决方案是提供一个空的多态基类,并让派生类专门化操作并处理它们的所有数据需求。
  • 您不能像这样混合运行时和编译时(重载)多态性。 type1-3 之间是什么关系? 那个可以用继承来表达吗?
  • Derived1::dataDerived2::dataBase::data 无关。派生类数据不会覆盖或替换基类数据,它们是独立存在的。您只能通过基本指针访问基本数据。
  • @nasw_264 为了使基类依赖于它们的派生类特征,通常使用的模式是CRTP。但是,在运行时决定使用什么会在某些方面受到限制。您需要引入另一层间接,例如引入纯virtualBaseBase类并通过虚函数访问data
  • 感谢大家的意见。我现在明白我目前的实现可能是错误的/不理想的。我是 C++ 新手,但你们给了我一些不错的选择。

标签: c++


【解决方案1】:

这是唯一 (*) 正确的咒语。

class Base {
  public:
     virtual void DoSomething() = 0;
     // no data
};

class Derived1 : public Base {
  public:
     void DoSomething() override;
  private:
      type2 data;
};

class Derived2 : public Base {
  public:
     void DoSomething() override;
  private:
      type3 data;
};

Base * obj;

if (...)
  obj = new Derived1();
else
  obj = new Derived2();

obj->DoSomething();

(*) 还有其他有效(如“运行时编译”)方式,但它们不是正确

【讨论】:

  • 如何通过 obj 访问“data”变量,因为它没有在基类中声明?
  • @nasw_264 你不能,你不应该,你也不需要。 所有对数据的访问都在 DoSomething 或其他虚拟函数中。这就是全部点。
  • 如果我需要将数据传递给另一个类怎么办?
  • Base的客户看不到数据,不知道数据,不关心数据。他们调用一个虚函数来做需要做的事情。而已。如果 虚函数 需要进一步传递数据,它就会这样做。 这就是重点。让它沉下去吧。
  • 感谢您的回答,但显然我仍然缺少一些东西。直接访问类变量是否被认为是不好的做法?
猜你喜欢
  • 1970-01-01
  • 2013-02-05
  • 2017-12-02
  • 2011-06-04
  • 2018-09-18
相关资源
最近更新 更多