一千萬個為什麽

搜索

C ++:繼承問題

我很難解釋我正在嘗試做什麽,我會嘗試:想象一下基本的 class A ,其中包含一些變量,以及一組派生自 A 的類所有這些都實現了一些方法 bool test(),它對從 A 繼承的變量進行操作。

class A {
   protected:
   int somevar;
  //...
};

class B : public A {
   public:
   bool test() {
      return (somevar == 42);
   }
};

class C : public A {
   public:
   bool test() {
      return (somevar > 23);
   }
};

// ... more classes deriving from A

現在我有一個 class A 的實例,我已經設置了 somevar 的值。

int main(int, char* []) {
    A a;
    a.somevar = 42;

現在,我需要某種容器,允許我叠代這個容器的元素 i ,在 a的上下文中調用 i :: test() ...即:

    std::vector<...> vec;
   //push B and C into vec, this is pseudo-code
    vec.push_back(&B);
    vec.push_back(&C);

    bool ret = true;
    for(i = vec.begin(); i != vec.end(); ++i) {
      //call B::test(), C::test(), setting *this to a
       ret &= ( a .* (&(*i)::test) )();
    }
    return ret;
 }

我怎樣才能做到這一點?我嘗試了兩種方法:

  1. forcing a cast from B::* to A::*, adapting a pointer to call a method of a type on an object of a different type (works, but seems to be bad);
  2. using std::bind + the solution above, ugly hack;
  3. changing the signature of bool test() so that it takes an argument of type const A& instead of inheriting from A, I don't really like this solution because somevar must be public.

修改</強>

解決方案(1)是:

typedef bool (A::*)() mptr;
std::vector vec;
vec.push_back(static_cast(&T::test));

std::vector::iterator i;
for(i = vec.begin(); i != vec.end(); ++i) {
   (a .* (*i))();
}

我不確定靜態演員是否安全。

最佳答案

最幹凈的解決方案是你建議的最後一個,在 A 中使 test 成為一個(純)虛擬函數:

virtual bool test(const A& value) = 0;

如果您對使用 somevar 公司感到困擾,請將其保密,並僅提供公共獲取功能:

int getvar() const {return somevar;}

轉載註明原文: C ++:繼承問題