簡體   English   中英

找出c ++中兩個對象類之間的繼承關系

[英]Find out inheritance relation between two objects classes in c++

我有一個抽象的C ++基類CPlugin。 從中可以直接和間接地衍生出許多類。 現在給出CPlugin * a,* b我需要找出,如果一個真正的類來自b的真實類。

即我想做這樣的事情:

void checkInheritance(CPlugin *a, CPlugin *b){
  if (getClass(a).isDerivedFrom(getClass(b)){
    std::cout << "a is a specialization from b's class" << std::endl;
  }
}

但是如何在C ++中實現“getClass”和“isDerivedFrom”?

你不能用C ++做到這一點。 在運行時獲取有關類型的一些信息的唯一方法是RTTI。 雖然RTTI不夠強大,無法滿足您的需求。 請解釋一下你想要達到的目標,然后你會得到更好的答案。

整個解決方案很難提供。 您要實現的是一種取決於兩個參數的具體類型的行為:這稱為雙重調度。 幾頁Modern C ++ Design(Andrei Alexandrescu)致力於這個子噴射。

一旦在單個代碼點知道兩個參數的實際具體類型,就可以使用boost type_traits: boost is_base_of來回答“isDerivedFrom”部分。

您可以使用動態強制轉換來測試對象是否屬於編譯時已知類型的子類型。 根據對象的運行時類型更改行為的機制是一個虛函數,它為您提供了一個在編譯時已知接收器類型的范圍。

因此,您可以通過虛函數實現相同的效果,因此您在一側編譯時具有類型,然后動態轉換以針對該類型檢查另一方:

#include <iostream>

class Plugin {
    public:
    virtual bool objectIsDerivedFromMyClass ( const Plugin & object ) const = 0;
};

template <typename T, typename BasePlugin = Plugin>
class TypedPlugin : public BasePlugin {
    public:
    virtual bool objectIsDerivedFromMyClass ( const Plugin & object ) const {
        return dynamic_cast<const T*> ( &object ) != 0;
    }

    private:
        int CheckMe(const T*) const;
};

class PluginA : public TypedPlugin<PluginA> {};
class PluginB : public TypedPlugin<PluginB, PluginA> {};
class PluginC : public TypedPlugin<PluginC> {};

int main () {
    PluginA a;
    PluginB b;
    PluginC c;

    std::cout << std::boolalpha
    << "type of a is derived from type of a " <<  a.objectIsDerivedFromMyClass ( a ) << '\n'
    << "type of a is derived from type of b " <<  b.objectIsDerivedFromMyClass ( a ) << '\n'
    << "type of b is derived from type of a " <<  a.objectIsDerivedFromMyClass ( b ) << '\n'
    << "type of c is derived from type of a " <<  a.objectIsDerivedFromMyClass ( c ) << '\n'
    ;

    return 0;
}

(您還可以添加一個T擴展TypedPlugin<T>的檢查)

雖然dynamic_cast在其參數上是運行時多態的,但它並不是完全雙重調度,所以它非常接近。

雖然對於任何更復雜的事情(或者如果你想堅持比較代表你所擁有的對象的運行時類型的對象的原始風格),你需要開始創建元類,或者使用提供元類的現有框架。 由於您正在討論插件,因此您可能已經在某處指定配置屬性或依賴項,並且也可以使用它。

Typeinfo和動態演員: http ://www.cplusplus.com/reference/std/typeinfo/type_info/

我真的不明白你所追求的是什么,但你總是可以通過以下方式使用虛擬方法:

template <typename Derived>
struct TypeChecker
{
  virtual bool ParentOf(CPlugin const& c) const
  {
    return dynamic_cast<Derived const*>(&c);
  }
};

現在,使用以下純虛方法擴充CPlugin類:

  virtual bool ParentOf(CPlugin const& c) const = 0;

並使從CPlugin派生的每個類CPlugin繼承自TypeChecker

class SomePlugin: public CPlugin, private TypeChecker<SomePlugin> {};

最后像這樣使用它:

void checkInheritance(CPlugin const& lhs, CPlugin const& rhs)
{
  if (!rhs.ParentOf(lhs)) return;

  std::cout << "lhs is derived from rhs' class\n";
}

但這並不能檢測它是否是一個特化,因為兩者完全屬於完全相同的類,這可以通過使用typeid運算符來檢測。

請注意為從CPlugin派生的每個類實現它的要求,您將理解為什么它如此復雜且容易出錯......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM