c++ - 我如何访问继承代码的不同部分

标签 c++ inheritance multiple-inheritance

您好,我有一个关于如何访问部分继承代码的问题。

假设我有这个 WorldObject,它是许多其他对象的基类。然后我有一个继承自 WorldObject 和抽象类 OpenAble 的 Chest 类,其中包含一些方法,例如打开和解锁。

在我的 main 中,我有一个 WorldObjects vector ,我用 for 循环遍历它。现在的问题是,我如何检查一个 worldobject 是否也是 OpenAble 的以及我如何访问 OpenAble 中的方法。

class WorldObject
{
...     //implementation
};

class OpenAble
{
public:
    OpenAble(){}
    virtual ~OpenAble(){}
    virtual void Open() = 0;
    virtual void Unlock(int k) = 0;
};

class Chest : public WorldObject, public OpenAble
{
...  //implementation
};

main()
{
std::vector<WorldObject> objVector;     //vector with several Worldobjects

for (int i =0; i < objVector.Size(); i++)
{
//check if a WorldObject is also of openable
//Do som actions like, open or unlock
//How?
}
};

最佳答案

你可以做一个dynamic_cast<OpenAble> .如果它是错误的类型,这将抛出一个错误,但考虑到对象很可能是错误的类型,这是相对昂贵的。

try{
  OpenAble& opener = dynamic_cast<OpenAble&>(worldObj);
} catch (std::bad_cast& ex){
  //not openable
}

顺便说一句:正如下面的评论所指出的,如果您在容器中使用指向基类的指针而不是引用,那么您可以(并且应该)使用 dynamic_cast 的指针版本,它将在这种情况下返回 null您的对象不是 OpenAble。检查你的情况比抛出和捕获异常更有效。

不过,我会推荐一种完全不同的方法。使用“OpenPolicy”注入(inject)您的基类。

例如

class CanOpenPolicy {
public:
  boolean canOpen(){ return true; };
  boolean canClose(){ return true; };
  boolean isOpen(){ return openState; };
  void open(){ openState = OPEN; };
  void close(){ openState = CLOSED; };
}

class NoOpenPolicy {
public:
  boolean canOpen(){ return false; };
  boolean canClose(){ return false; };
  boolean isOpen(){ return CLOSED; };
  void open(){ throw IllegalWorldObjectAction("OpenPolicy disallows operation"); };
  void close(){ throw IllegalWorldObjectAction("OpenPolicy disallows operation"); };
}

//injection via template (no need for base "OpenPolicy" class, maybe some
// obscure error codes at compile though)
// Implicit interface based on how you use the injected policy.
template<OpenPol>
class WorldObject {
private: 
  // CTOR part of the injected contract so you are not tied to knowing how to 
  // build the policy. This is a key benefit over interface based injection.
  OpenPol openPol; 
  ...
public:
  ...
  void open(){
    if(openPol.canOpen()){
      openPol.open();
    }
  }
  ...
}

那没有经过测试或任何东西。只是为了说明这个想法。您可以为不同的可能操作添加多个策略,最好的是您不需要很多层次结构。

要使用它,只需执行如下操作:

std::unique_ptr<WorldObject>( new Chest() );
std::unique_ptr<WorldObject>( new Banana() );
std::unique_ptr<WorldObject>( new Chair() );

哪里:

class Chest : public WorldObject<CanOpenPolicy> {
   // Very little implementation in here.
   // Most of it is handled in the base class and the injected policies :)
}
class Banana: public WorldObject<CanOpenPolicy> {
}
class Chair : public WorldObject<NoOpenPolicy> {
}

关于c++ - 我如何访问继承代码的不同部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22322293/

相关文章:

c++ - 死亡钻石和作用域解析运算符 (c++)

c++ - 破译 C/C++ 函数指针类型定义的工具

c++ - 在新数组中存储字符数组地址

c++ - QObject的多重继承

javascript - for-in 与没有继承属性的 Object.keys forEach

java - 内部类变量的可见性

python - 项目的多重继承与组合的讨论(+其他事情)

C++11 错误不匹配调用 main 之外的 Ifstream

c++ - 为什么我不能使用函数调用来声明数组的长度?

c# - 搞乱泛型和图形建模