双继承和多态。如何从一个基类中拥有两个独立的成员?
Posted
技术标签:
【中文标题】双继承和多态。如何从一个基类中拥有两个独立的成员?【英文标题】:Double inheritance and polymorphism. How to have two separated members from one base class? 【发布时间】:2017-12-09 14:57:48 【问题描述】:我需要对从 BaseA 继承的对象使用 do_something
的多态性,但我的 D 对象应该有两个名为 enabled
的独立成员。我的意思是 D::changeEnabled()
应该改变 SecondBaseB::BaseA::enabled = 0
和 SecondBaseC::BaseA::enabled = 0
并且这两个成员应该是分开的(不同的)。是否可以具有多态性而不使用虚拟继承?没有virtual public BaseA
我有模棱两可的错误。但是对于虚拟继承,我只有一个BaseA::enabled
。
//
// main.cpp
//
#include <iostream>
#include "D.h";
void do_something(BaseA& o)
o.changeEnabled();
int main()
SecondBaseB b;
SecondBaseC c;
D d;
do_something(b);
do_something(c);
do_something(d);
std::cout « "Hello, World!" « std::endl;
return 0;
//
// BaseA.h
//
class BaseA
protected:
bool enabled;
public:
BaseA();
virtual void changeEnabled() = 0;
;
//
// BaseA.cpp
//
#include "BaseA.h"
BaseA::BaseA() : enabled(true)
//
// SecondBaseB.h
//
class SecondBaseB : virtual public BaseA
public:
virtual void changeEnabled();
;
//
// SecondBaseB.cpp
//
#include "SecondBaseB.h"
void SecondBaseB::changeEnabled()
enabled = !enabled;
//
// SecondBaseC.h
//
#include "BaseA.h"
class SecondBaseC : virtual public BaseA
public:
virtual void changeEnabled();
;
//
// SecondBaseC.cpp
//
#include "SecondBaseC.h"
void SecondBaseC::changeEnabled()
enabled = !enabled;
//
// D.h
//
#include "SecondBaseB.h"
#include "SecondBaseC.h"
class D : public SecondBaseB, public SecondBaseC
public:
virtual void changeEnabled();
;
换个说法。我有以下场景:带有engine
成员的基础抽象类Car。我创建了从 Car 继承的 DieselCar 和 ElectricCar。然后我想创建 HybridCar,它将继承自 DieselCar 和 ElectricCar 并有两个不同的 engines
。使用虚拟继承只有一个引擎。如果不使用virtual
,我将无法完成以下操作:
void testDrive(Car* c)
c->drive();
c->drive();
HybridCar h;
ElectricCar e;
testDrive(&h);
testDrive(&e)
【问题讨论】:
模板和std::enable_if()
是处理此类情况的绝佳工具。
如果有两个不同的enabled
成员,你希望do_something(d)
做什么?
使用virtual
基类表示您只需要一个该类型的基对象。既然你想要两个,不要使用虚拟继承。 D
必须明白有两个基础并采取相应的行动。
【参考方案1】:
谈论您的 Car 场景,要获得关于 Car 子类的多个信息,这些子类不止一个 Engine,可以使用 Composite 重构代码模式,以这种方式:
汽车拥有发动机 Engine 是一个接口或抽象类,其作用类似于 组件 Leaf 是 Engine 的具体子类,其含义类似于 ElectricEngine、DieselEngine 等...李> PowerUnit 的作用类似于 Composite,因此它拥有对某些 Engine 的引用然后Car的每个具体子类的每个构造函数都初始化属性
Engine* engine;
在抽象类Car中以正确的方式声明。 例如,
ElectricCar()
//other members
engine=new ElectricEngine();
DieselCar()
//other members
engine=new DieselCar();
HybridCar()
//hybrid car is composed by an electric and diesel engine
engine=new PowerUnit(Engine* engines);
如果抽象类看起来像
class Engine
private bool enabled;
public:
virtual Engine* getEngine(int number=0) return this;
virtual final bool isEnabled()return this->enabled;
virtual final void setEnabled(bool value) this->enabled=value;
getEngine()
方法必须在子类 PowerUnit 的真实函数中实现。
class PowerUnit
private:
Engine*[] engines;
public:
PowerUnit()
engines[0]=new ElectricCar();
engines[1]=new DieselCar();
getEngine(int number) return engines[number];
最后,如果客户 (Car) 想要检查混合动力汽车哪个引擎处于活动状态(或两者都处于活动状态),它可以使用指针 engine,如以下方式检查第一个引擎是否处于活动状态:
engine->getEngines(0)->isEnabled;
【讨论】:
以上是关于双继承和多态。如何从一个基类中拥有两个独立的成员?的主要内容,如果未能解决你的问题,请参考以下文章