C++ C++;类型多态性
我试图创建一个节点,该节点有一个类型为T的变量,C++ C++;类型多态性,c++,templates,inheritance,polymorphism,virtual,C++,Templates,Inheritance,Polymorphism,Virtual,我试图创建一个节点,该节点有一个类型为T的变量,T data以及存储指向其父节点的指针节点基*父节点 这些类看起来是这样的: class Node: public NodeBase { T data; NodeBase *parent; public: Node(T); void setData(T); T * getData(void); void setParent(NodeBase * const); NodeBase * getPa
T data代码>以及存储指向其父节点的指针节点基*父节点代码>
这些类看起来是这样的:
class Node: public NodeBase {
T data;
NodeBase *parent;
public:
Node(T);
void setData(T);
T * getData(void);
void setParent(NodeBase * const);
NodeBase * getParent(void);
};
class NodeBase {
};
我原以为我可以在节点库
中放置一个纯虚函数,但您必须指定返回类型,而且由于节点库
没有类型,我无法指定虚T*getData(void)=0代码>
我遇到问题的具体案例:
Node<char> n1 = Node('A');
Node<int> n2 = Node(63);
n1.setParent(&n2);
NodeBase *pNode = n1.getParent();
pNode->getData(); // Error: BaseNode has no member 'getData()'
Node n1=节点('A');
节点n2=节点(63);
n1.setParent(&n2);
NodeBase*pNode=n1.getParent();
pNode->getData();//错误:BaseNode没有成员“getData()”
您有pNode(child),因此您可以直接使用它来getData()
,其次,您的基类对getData()
一无所知,因此使用上置指针无法调用它
您有pNode(child),因此您可以直接使用它来getData()
,其次,您的基类对getData()
一无所知,因此使用上置指针您无法调用它。我相信您混淆了运行时多态性和编译时多态性。模板提供了更晚的版本。解决此问题的一个可能方法是将NodeBase
设置为模板类:
template <class T>
class NodeBase {
public:
virtual T getData() = 0;
};
template <class T>
class Node : NodeBase<T> {
T data;
NodeBase *parent;
public:
Node(T);
void setData(T);
T getData(void);
void setParent(NodeBase<T> * const);
NodeBase<T> * getParent(void);
};
模板
类节点基{
公众:
虚拟T getData()=0;
};
样板
类节点:NodeBase{
T数据;
节点基*父节点;
公众:
节点(T);
无效设置数据(T);
T获取数据(无效);
void setParent(NodeBase*const);
NodeBase*getParent(无效);
};
注意,我让getData
返回T
,而不是T*
。(是否有理由返回指针?我认为您混淆了运行时多态性和编译时多态性。模板提供了更晚的版本。解决此问题的一个可能方法是将NodeBase
设置为模板类:
template <class T>
class NodeBase {
public:
virtual T getData() = 0;
};
template <class T>
class Node : NodeBase<T> {
T data;
NodeBase *parent;
public:
Node(T);
void setData(T);
T getData(void);
void setParent(NodeBase<T> * const);
NodeBase<T> * getParent(void);
};
模板
类节点基{
公众:
虚拟T getData()=0;
};
样板
类节点:NodeBase{
T数据;
节点基*父节点;
公众:
节点(T);
无效设置数据(T);
T获取数据(无效);
void setParent(NodeBase*const);
NodeBase*getParent(无效);
};
注意,我让getData
返回T
,而不是T*
。(有返回指针的理由吗?C++是静态类型的,所以每次编写这样的代码时:
NodeBase *pNode = n1.getParent();
pNode->getData(); // Error: BaseNode has no member 'getData()'
编译器需要知道getData()
的类型。在您的例子中,您希望它是int(void)
或char(void)
-不返回参数的函数char
或int
这是有办法的。策略将取决于您的情况。返回类型有几种情况:
- 一组固定的球头-使用一个接头
- 一组固定的内置项或类,但类型永远不会更改-使用联合
- 内置或类的修复集,但类型可能会更改-使用boost变体
- 任何其他情况-使用boost Any
总之,向返回上述数据结构之一的基类(非模板化)添加一个虚拟函数。boost的文档很容易在网上找到
这是C++之所以困难的原因,是因为其他语言(尤其是动态语言)隐藏了困难。进行函数调用时,会分配空间(通常在堆栈上以获得最佳速度),并将返回值复制到该空间中。如果要返回未知类型,则需要在所有可能的返回类型(联合,可能是boost变量?)中提供最大可用空间,或者从堆中分配该空间(boost any)。许多静态类型语言仅为前者提供良好的支持
如果你想自己做的话,C++确实有一些有用的特性
#include <iostream>
#include <typeinfo>
using namespace std;
struct NodeBase {
virtual ~NodeBase(){}
};
template<typename T>
struct Node: public NodeBase {
T data;
NodeBase *parent;
Node(T data, NodeBase* parent = nullptr)
: data(data), parent(parent)
{}
~Node(){}
};
int main()
{
Node<int> n2(63);
Node<char> n1('A', &n2);
NodeBase* b = n1.parent; //pointer to n2
if(typeid(*b) == typeid(Node<int>))
cout << ((Node<int>*) b)->data << endl;
return 0;
}
#包括
#包括
使用名称空间std;
结构节点基{
虚拟~NodeBase(){}
};
样板
结构节点:公共节点库{
T数据;
节点基*父节点;
节点(T数据,节点基*父节点=nullptr)
:数据(数据),父(父)
{}
~Node(){}
};
int main()
{
节点n2(63);
节点n1('A',和n2);
NodeBase*b=n1.parent;//指向n2的指针
if(typeid(*b)=typeid(节点))
cout dataC++是静态类型的,所以每次编写这样的代码时:
NodeBase *pNode = n1.getParent();
pNode->getData(); // Error: BaseNode has no member 'getData()'
编译器需要知道getData()
的类型。在您的例子中,您希望它是int(void)
或char(void)
-不返回参数的函数char
或int
有很多解决方法。策略将取决于您的情况。退货类型有几种情况:
- 一组固定的球头-使用一个接头
- 一组固定的内置项或类,但类型永远不会更改-使用联合
- 内置或类的修复集,但类型可能会更改-使用boost变体
- 任何其他情况-使用boost Any
总之,向返回上述数据结构之一的基类(非模板)添加一个虚拟函数
这是C++中更困难的原因,因为其他语言(尤其是动态语言)隐藏困难。当进行函数调用时,会分配空间(通常在堆栈上以最佳速度分配),并将返回值复制到该空间中。如果要返回未知类型,则需要在所有可能的返回类型(union,可能是boost变量)中提供最大可用空间或者从堆中分配空间(boostany)。许多静态类型语言仅为前者提供良好的支持
如果你想自己做的话,C++确实有一些有用的特性
#include <iostream>
#include <typeinfo>
using namespace std;
struct NodeBase {
virtual ~NodeBase(){}
};
template<typename T>
struct Node: public NodeBase {
T data;
NodeBase *parent;
Node(T data, NodeBase* parent = nullptr)
: data(data), parent(parent)
{}
~Node(){}
};
int main()
{
Node<int> n2(63);
Node<char> n1('A', &n2);
NodeBase* b = n1.parent; //pointer to n2
if(typeid(*b) == typeid(Node<int>))
cout << ((Node<int>*) b)->data << endl;
return 0;
}
#包括
#包括
使用名称空间std;
结构节点基{
虚拟~NodeBase(){}
};
样板
结构节点:公共节点库{
T数据;
节点基*父节点;