繁体   English   中英

C ++:继承问题

[英]C++: inheritance problem

我很难解释我正在尝试做什么,我会尝试:想象一个包含一些变量的基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这个容器中,调用i::test()的背景下a ...那就是:

    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. 强制从B :: *转换为A :: *,调整指针以调用不同类型的对象上的类型的方法(工作,但似乎是坏的);
  2. 使用std :: bind +上面的解决方案,丑陋的黑客;
  3. 更改bool test()的签名,以便它采用类型为const A&的参数而不是继承自A,我不太喜欢这个解决方案,因为somevar必须是公共的。

编辑:

解决方案(1)是:

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

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

我不确定静态演员是否安全。

最干净的解决方案是你建议的最后一个,在A中使test成为一个(纯)虚函数:

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

如果你somevar了使somevar公开保持私有并只提供公共get函数:

int getvar() const {return somevar;}

您正尝试在A上调用BC方法。 不要那样做。

您需要创建BC实际实例,在vector<A*> <A *>中存储指向它们的指针,并在迭代期间调用在A定义的纯虚拟test()成员函数(其中B::testC::test将覆盖)。

添加“virtual bool test()= 0;” 在A的定义中

然后,您可以在循环中执行以下操作:

ret = (ret && i->test());

BTW:“&=”执行“按位和”,你可能想要逻辑和执行(&&)。

另外:你在向量中添加指针的B和C实例都包含继承变量的副本,它们都是该变量的独立实例。

我认为你的代码,如此处所示,是非常有缺陷的。 想一想你想要实际实现的目标是什么?

您想对单个变量运行多种布尔测试,看看它是否与所有变量匹配? 或者每个约束是否真的要针对它自己的变量进行测试,你想得到所有那些独立测试的“布尔值”?

到目前为止,这是最干净的解决方案。 它使用static

struct A {
   int somevar;
};

struct B {
   static bool test(const A& a) {
      return (a.somevar == 42);
   }
};

std::vector<bool (*)(const A&)> vec;

template<typename T>
void push(const T&) {
   vec.push_back(&T::test);
}

简单的解决方案:

A类更改为:

class A {
public:
    virtual bool test() const = 0;
protected:
    int somevar;
    // ...
};

现在,我需要一些允许我迭代这个容器的元素i的容器,在一个上下文中调用i :: test()。

typedef std::vector<A*> ItemList;
ItemList items;
for(ItemList::const_iterator i = items.begin(); i != items.end(); ++i)
{
    if((*i)->test())
        ; // ???
}

所以我想知道OP想要做什么,这不是......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM