如何继承和实现纯虚方法与抽象类作为参数? [英] How to inherit and implement a pure virtual method with the abstract class as a parameter?

查看:267
本文介绍了如何继承和实现纯虚方法与抽象类作为参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个抽象类 Node ,它包含一个纯虚方法stub matches ,需要另一个 Node (即将 Node 子类化的实例)作为参数。

  class Node; // forward declaration 

class Node {
public:
Node():parentNode(this){}
virtual〜Node(){}

Node * parentNode;

virtual bool matches(const Node& node)const = 0;
};

如何在子类中实现 matches 这样参数可以是子类型,而不是 Node



我想要像下面这样从 Node 注册为实现版本的合同,这样我可以访问 NodeImpl 具体属性作为函数的一部分,否则我无法做到:

  class NodeImpl:public Node {
private:
int foo;
...
};

...

bool NodeImpl :: matches(const NodeImpl& n)const {
return this-> foo == n.foo;
}






确实有一个尝试使用模板实现这种效果,但我不知道我做的是对的。我发现自己在我的代码传播模板,遇到了无数的错误,并希望得到一个想法是什么正确的方法,这正是在我浪费更多的时间,什么也可能是错误的做事方式。)



我尝试是:

 模板< class T& 
class Node;

template< class T>
class Node {
public:
Node():parentNode(this){}
virtual〜Node(){}

Node * parentNode;

virtual bool matches(const T& node)const = 0;
};

这样我可以在模板函数中一般调用匹配:

 模板< class T> 
void pathComp(Node< T>& currNode,Node< T>& rootNode){
Node< T> * node =& currNode;
while(node-> matches(rootNode)){
...
}
}

我不能得到这个方法工作,加上我不喜欢我似乎不得不有 class NodeImpl:public Node< NodeImpl> 作为我的继承,关于这一点似乎不太对。关于我是否在正确的线路上的任何建议都是伟大的!

解决方案

一般,因为它不会是类型安全的。例如:

  struct Node {virtual bool matches(const Node&)const = 0; } 
struct NodeA:Node {virtual bool matches(const NodeA&)const; };
struct NodeB:Node {virtual bool matches(const NodeB&)const; };

NodeA a; //编译器不允许,但如果它...
NodeB b;
Node& c = a;
c.matches(b); //哎呀!

你在谈论实现它的方式,会有一个假设 b 是与 a 相同的类型,但是编译器没有办法验证一般的假设,所以它不会去



但是,如果您使用相同类型的两个节点,则可以始终使用 matches()函数不是虚拟的:

  struct Node {} 
struct NodeA:Node {bool matches &)const; };

NodeA a1;
NodeA a2;
a1.matches(a2); // fine


I have an abstract class Node which contains a pure virtual method stub matches, requiring another instance of a Node (i.e. instance of something that subclasses Node) as a parameter.

class Node; // forward declaration

class Node {
public:
    Node() : parentNode(this) {}
    virtual ~Node() {}

    Node* parentNode;

    virtual bool matches(const Node& node) const = 0;
};

How can I implement matches in a subclass such that the parameter can be of the subclasses type as opposed to Node?

E.g. I want something like the following to register as the implemented version of the contract from Node, so that I can access NodeImpl specific properties as part of the function which I would otherwise be unable to do:

class NodeImpl : public Node {
private:
    int foo;
    ...
};

...

bool NodeImpl::matches(const NodeImpl& n) const {
    return this->foo == n.foo;
}


(I did have a try using templates to achieve this sort of effect, but I wasn't sure that I was doing it quite right. I found myself propagating the templates all over my code and encountering a myriad errors as such, and was hoping to get an idea of what the right method for this exactly is before I waste yet more time on what might well be also the wrong way of doing things.)

What I tried was:

template <class T>
class Node;

template <class T>
class Node {
public:
    Node() : parentNode(this) {}
    virtual ~Node() {}

    Node* parentNode;

    virtual bool matches(const T& node) const = 0;
};

So that I could call matches generically in a template function like so:

template <class T>
void pathComp(Node<T>& currNode, Node<T>& rootNode) {
    Node<T> *node = &currNode;
    while (node->matches(rootNode)) {
        ...
    }
}

I couldn't quite get this method to work, plus I didn't like how I seemingly had to have class NodeImpl : public Node<NodeImpl> as my inheritance, something about that didn't seem quite right. Any advice as to whether I was on the right lines or not would be great!

解决方案

You can't really do that in general, because it wouldn't be type-safe. For example:

struct Node { virtual bool matches(const Node &) const = 0; }
struct NodeA : Node { virtual bool matches(const NodeA &) const; };
struct NodeB : Node { virtual bool matches(const NodeB &) const; };

NodeA a; // compiler doesn't allow, but if it did...
NodeB b;
Node &c = a;
c.matches(b); // oops!

The way you are talking about implementing it, there would be an assumption that b was the same type as a, but there is no way for the compiler to verify that assumption in general, so it isn't going to allow it.

However, if you are using two nodes of the same type, you can always have the matches() function just not be virtual:

struct Node {   }
struct NodeA : Node {  bool matches(const NodeA &) const; };

NodeA a1;
NodeA a2;
a1.matches(a2); // fine

这篇关于如何继承和实现纯虚方法与抽象类作为参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆