简体   繁体   English

C ++:继承问题

[英]C++: inheritance problem

It's quite hard to explain what I'm trying to do, I'll try: Imagine a base class A which contains some variables, and a set of classes deriving from A which all implement some method bool test() that operates on the variables inherited from A . 我很难解释我正在尝试做什么,我会尝试:想象一个包含一些变量的基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

Now I have an instance of class A and I have set the value of somevar . 现在我有一个class A的实例,我已经设置了somevar的值。

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

Now, I need some kind of container that allows me to iterate over the elements i of this container, calling i::test() in the context of a ... that is: 现在,我需要某种容器,让我来遍历元素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;
 }

How can I do this? 我怎样才能做到这一点? I've tried two methods: 我试过两种方法:

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

EDIT: 编辑:

Solution (1) is: 解决方案(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))();
}

I'm not sure the static cast is safe. 我不确定静态演员是否安全。

The cleanest solution is the last one you suggest, make test a (pure) virtual function in A : 最干净的解决方案是你建议的最后一个,在A中使test成为一个(纯)虚函数:

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

If you're bothered with making somevar public keep it private and supply only a public get function: 如果你somevar了使somevar公开保持私有并只提供公共get函数:

int getvar() const {return somevar;}

You are trying to call B and C methods on an A . 您正尝试在A上调用BC方法。 Don't do that. 不要那样做。

You need to create actual instances of B and C , store pointers to them in a vector<A*> and, during iteration, call a pure virtual test() member function defined in A (which B::test and C::test will override). 您需要创建BC实际实例,在vector<A*> <A *>中存储指向它们的指针,并在迭代期间调用在A定义的纯虚拟test()成员函数(其中B::testC::test将覆盖)。

Add "virtual bool test() = 0;" 添加“virtual bool test()= 0;” in the definition of A. 在A的定义中

Then you can do the following in your loop: 然后,您可以在循环中执行以下操作:

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

BTW: "&=" does a "bitwise and" and you probably want the logical and to be performed (&&). BTW:“&=”执行“按位和”,你可能想要逻辑和执行(&&)。

Also: the instances of B and C you put pointers to in your vector all contain copies of the inherited variable, they are all independant instantiations of that variable. 另外:你在向量中添加指针的B和C实例都包含继承变量的副本,它们都是该变量的独立实例。

I think your code, as shown here, is pretty flawed. 我认为你的代码,如此处所示,是非常有缺陷的。 Think more about what it is you want to actually achieve? 想一想你想要实际实现的目标是什么?

Do you want to run a multiplicity of boolean tests on a single variable and see if it matches all of them? 您想对单个变量运行多种布尔测试,看看它是否与所有变量匹配? Or is each contraint really to be tested against its own variable and you want to get the "boolean and" of all those independent tests? 或者每个约束是否真的要针对它自己的变量进行测试,你想得到所有那些独立测试的“布尔值”?

This is the cleanest solution so far. 到目前为止,这是最干净的解决方案。 It uses static : 它使用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);
}

The simple solution: 简单的解决方案:

Change class A to: A类更改为:

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

Now, I need some kind of container that allows me to iterate over the elements i of this container, calling i::test() in the context of a. 现在,我需要一些允许我迭代这个容器的元素i的容器,在一个上下文中调用i :: test()。

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

So I'm wondering what the OP wants to do that this doesn't... 所以我想知道OP想要做什么,这不是......

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

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