在C++中使用继承时避免不需要的函数声明/定义

RDK*_*RDK 4 c++ virtual inheritance

经过长时间的C风格程序编码,我才开始"获得"OOP.所以我怀疑可能有标准的方法来处理我所面临的情况.我有一个应用程序,其类层次结构如下所示:

#include <iostream>
using namespace std;

class A {
public:
  virtual int intf() { return 0;} // Only needed by B
  virtual double df() {return 0.0;} // Only needed by C
};    
class B : public A {
  int intf() {return 2;}
  // B objects have no use for df()
};    
class C : public B {
  double df() {return 3.14;}
  // C objects have no use for intf()
};    
int main(){
  // Main needs to instantiate both B and C.
  B b;
  C c;
  A* pa2b = &b;
  A* pa2c = &c;

  cout << pa2b->intf() << endl;
  cout << pa2b->df() << endl;
  cout << pa2c->intf() << endl;
  cout << pa2c->df() << endl;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在这个程序编译并运行正常.但是,我对它的设计有疑问.A类是通用接口,不需要实例化.B类和C类需要.关于函数:B需要intf()而不是C,而C需要df()而不是B.如果我在A中使intf(){df()}纯虚,那么就没有合理的定义对于B {C},df(){intf()}.

编辑:B和C共享一些数据成员以及f()以外的一些成员函数.我没有向我展示我的精简代码.

最后,作为标准,我的应用程序需要通过指向A的指针访问B和C.所以我的问题是:有没有办法'清理'这个设计,以便不需要/空的成员函数定义(比如我有在A)的声明/定义中完成可以消除吗?这些类之间存在明确的"IS-A"关系.所以即使我分享每个新手对继承的兴奋,我也不觉得我已经延伸了我的设计,所以我可以使用继承.

背景以防万一:我正在实施一个回归套件.A类实现每个回归共有的函数和矩阵(例如依赖变量和独立变量).B类是逻辑回归,有两个类('0'和'1'),定义了成本函数,以及两类逻辑回归的训练算法.C类是多类逻辑回归.它通过使用"one-vs-all"算法训练多个类来扩展B类.因此,在某种意义上,如果您认为您感兴趣的类作为正例,而所有其他作为反面例子,则C是二元逻辑回归.然后,您为每个类执行此操作以实现多类回归.有问题的函数(intf和df)返回输出.在逻辑回归的情况下,返回值是向量,而对于多类回归,它是一个矩阵.并且,如上所述,B和C对彼此的返回功能没有任何用处.除了我似乎无法消除A(回归类)中的冗余定义.

谢谢你的帮助.

rya*_*an0 5

请看Liskov替换原则(http://en.wikipedia.org/wiki/Liskov_substitution_principle).它声明子类必须履行与超类相同的合同.在您的示例中,两个子类都不会这样做."Is-A"关系不足以证明继承的合理性.

一种选择是使用单个模板方法,如下所示:

template <typename T>
class A<T> {
    T getValue();
}

class B : A<int> {
    int getValue();
}

class C: A<double> {
    double getValue();
}
Run Code Online (Sandbox Code Playgroud)

这将允许两个子类履行合同,同时允许方法的返回类型根据子类定义而变化.

如果你想学习更多面向对象的编程"最佳实践",google"Robert Martin SOLID"