C ++模板和多态
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++模板和多态相关的知识,希望对你有一定的参考价值。
我正在研究决策树结构,因为我将使用不同代理的类似决策结构,所以我决定使用模板来构建基本功能。
目前我有一个名为BC_IsEnemyCloseDecision
的类,它继承自模板类。链是BC_IsEnemyCloseDecision -> DT_BoolDecision<T> -> DT_Decision<T> -> DT_Node<T>
DT_Node
类:
template <class entity_type>
class DT_Node
{
public:
DT_Node() {}
virtual ~DT_Node()
{
mNodes.clear();
}
virtual DT_Node* decide(entity_type* pAgentPtr) = 0;
virtual void addChild(std::unique_ptr<DT_Node>&& pNewChild)
{
mNodes.emplace_back( std::move(pNewChild) );
}
protected:
std::vector< std::unique_ptr<DT_Node> > mNodes;
};
DT_Decision类:
template <class entity_type>
class DT_Decision : public DT_Node<entity_type>
{
public:
DT_Decision()
: DT_Node<entity_type>()
{
}
virtual ~DT_Decision()
{
}
DT_Node<entity_type>* decide(entity_type* pAgentPtr)
{
return getBranch(pAgentPtr)->decide(pAgentPtr);
}
protected:
virtual DT_Node<entity_type>* getBranch(entity_type* pAgentPtr) = 0;
};
DT_BoolDecision
类:
template <class entity_type>
class DT_BoolDecision : public DT_Decision<entity_type>
{
public:
enum eNODE_TYPE{ eNT_TRUE_NODE = 0, eNT_FALSE_NODE};
DT_BoolDecision()
: DT_Decision<entity_type>(),
BRANCH_NUMBER(2)
{
}
virtual ~DT_BoolDecision()
{
}
void addChild(std::unique_ptr< DT_Node<entity_type> >&& pNewChild)
{
this->mNodes.emplace_back( std::move(pNewChild) );
}
void addChild(const eNODE_TYPE pNodeType, std::unique_ptr< DT_Node<entity_type> >&& pNewChild)
{
if(this->mNodes.size() <BRANCH_NUMBER)
{
this->mNodes.emplace( this->mNodes.begin() + (int)pNodeType, std::move(pNewChild) );
}
}
protected:
virtual bool performTest(entity_type* pAgentPtr) = 0;
DT_Node<entity_type>* getBranch(entity_type* pAgentPtr)
{
if( performTest(pAgentPtr) )
{
return this->mNodes[eNODE_TYPE::eNT_TRUE_NODE].get();
}
return this->mNodes[eNODE_TYPE::eNT_FALSE_NODE].get();
}
const int BRANCH_NUMBER;
};
BC_IsEnemyCloseDecision
类:
// int for a simple test
class BC_IsEnemyCloseDecision : public DT_BoolDecision<int>
{
public:
BC_IsEnemyCloseDecision();
virtual ~BC_IsEnemyCloseDecision();
protected:
bool performTest(int* pAgentPtr);
};
DT_Action(如果您需要):
template <class entity_type>
class DT_Action : public DT_Node<entity_type>
{
public:
DT_Action()
: DT_Node<entity_type>()
{}
virtual ~DT_Action() {}
DT_Node<entity_type>* decide(entity_type* pAgentPtr) { return this; }
void addChild(std::unique_ptr< DT_Node<entity_type> >&& pNewChild) {}
virtual void performAction(entity_type* pAgent) = 0;
};
最后DecisionTree
类:
template <class entity_type>
class DecisionTree
{
public:
DecisionTree(entity_type* pAgentPtr)
{
mAgentPtr = pAgentPtr;
}
DecisionTree(entity_type* pAgentPtr, std::unique_ptr< DT_Node<entity_type> >&& pRoot)
{
mAgentPtr = pAgentPtr;
mRoot = std::move(pRoot);
}
~DecisionTree()
{
}
void addRoot(std::unique_ptr< DT_Node<entity_type> >&& pRoot)
{
mRoot = std::move(pRoot);
}
void decide()
{
DT_Action<entity_type>* resultantAction = (DT_Action<entity_type>*)(mRoot->decide(mAgentPtr));
if(resultantAction != nullptr)
{
resultantAction->performAction(mAgentPtr);
}
else
{
std::cout<<"ERROR! DT! FACED WITH A NULL DT_ACTION";
}
}
private:
std::unique_ptr<DT_Node<entity_type>> mRoot;
entity_type* mAgentPtr;
};
编码结束后,我决定用简单的类型测试它(我选择了int
)并执行了以下操作:
int test= 6;
std::unique_ptr<BC_IsEnemyCloseDecision> testRoot = std::make_unique<BC_IsEnemyCloseDecision>();
std::unique_ptr<BC_IsEnemyCloseDecision> testNode = std::make_unique<BC_IsEnemyCloseDecision>();
testRoot->addChild(testNode); // Error: No matching member function for call to 'addChild'
testRoot->addChild(DT_BoolDecision<int>::eNODE_TYPE::eNT_TRUE_NODE, testNode); // Error: No matching member function for call to 'addChild'
DecisionTree<int> dt(&test);
dt.addRoot(testRoot); // Error: No viable conversion from 'unique_ptr<BC_IsEnemyCloseDecision>' to 'unique_ptr<DT_Node<int>>
dt.decide();
并收到No matching member function for call to 'addChild'
和No viable conversion from 'unique_ptr<BC_IsEnemyCloseDecision>' to 'unique_ptr<DT_Node<int>>
错误。
我无法找到与我的问题相关的任何有用信息,所以我没有解决它的见解。
答案
你的错误归结为
struct Receiver
{
void method(std::unique_ptr<int> ptr) {}
};
int main()
{
Receiver receiver;
std::unique_ptr<int> ptr = std::make_unique<int>(10);
receiver.method(ptr); // Error: No matching member function for call to 'method'
}
这是因为你试图复制unique_ptr
s。你需要移动它们。而这样做,移动来自unique_ptr
将是空的。
std::unique_ptr<BC_IsEnemyCloseDecision> testRoot = std::make_unique<BC_IsEnemyCloseDecision>();
std::unique_ptr<BC_IsEnemyCloseDecision> testNode = std::make_unique<BC_IsEnemyCloseDecision>();
testRoot->addChild(std::move(testNode));
// You don't have a node in testNode anymore, so you need a new one to add again
testNode = std::make_unique<BC_IsEnemyCloseDecision>();
testRoot->addChild(DT_BoolDecision<int>::eNODE_TYPE::eNT_TRUE_NODE, std::move(testNode));
int test= 6;
DecisionTree<int> dt(&test);
dt.addRoot(std::move(testRoot));
dt.decide();
以上是关于C ++模板和多态的主要内容,如果未能解决你的问题,请参考以下文章
C++--模板的概念和意义深入理解函数模板类模板的概念和意义