Прежде всего, я хотел бы заранее поблагодарить любого, кто отвечает на этот вопрос. Ваша помощь очень ценится. Это моя первая публикация здесь, поэтому, пожалуйста, простите меня, если я напишу с плохим этикетом.C++ размещение проблемы «const».
Мой вопрос о методе прототипа:
void copySubtree(Node<T> * & target, Node<T> * const & original);
и когда я называю copySubtree()
позже в combineTrees()
. Поскольку код в настоящее время, он строит. Но то, что я изначально был был:
void copySubtree(Node<T> * & target, const Node<T> * & original);
который дал мне ошибку:
error C2664: 'RootedBinaryTree<T>::copySubtree' : cannot convert parameter 2 from 'RootedBinaryTree<T>::Node<T> *const ' to 'const RootedBinaryTree<T>::Node<T> *&'
Я знаю, что когда вы положили const
перед типом данных в параметре мешает вам изменения указанного параметра в вашем метод, но я не знаю, что он делает, когда вы кладете его после типа данных, и я не уверен, что мое построение кода с размещением const
после типа данных было не просто случайностью. Что делает размещение const
после типа данных? Будет ли у моего кода ужасные проблемы времени выполнения так, как он в настоящее время написан?
[Также: Я пытаюсь написать определения метода класса шаблонов двоичного дерева, основанного на двоичном дереве (поэтому некоторые из методов пустые, и в комментариях есть некоторые случайные заметки). Поэтому я приношу извинения за любые неудобства, вызванные тем, что]
Вот соответствующий код:.
RootedBinaryTree.h
#ifndef ROOTEDBINARYTREE_H
#define ROOTEDBINARYTREE_H
template <class T>
class RootedBinaryTree
{
private:
template <class T>
struct Node
{
T nodeData;
Node<T> * leftChild;
Node<T> * rightChild;
};
Node<T> * root;
Node<T> * currentPosition;
void copySubtree(Node<T> * & target, Node<T> * const & original);
void deleteSubtree(Node<T> * n);
public:
RootedBinaryTree(const T & rootData);
RootedBinaryTree(const RootedBinaryTree<T> & original);
~RootedBinaryTree();
void toRoot();
bool moveLeft();
bool moveRight();
T getData() const {return currentPosition->nodeData;};
RootedBinaryTree<T> & operator=(const RootedBinaryTree<T> & RHS);
void combineTrees(const RootedBinaryTree<T> & leftTree, const RootedBinaryTree<T> & rightTree);
void setNodeData(const T & nodeData);
};
#endif
RootedBinaryTree.cpp
#ifndef ROOTEDBINARYTREE_CPP
#define ROOTEDBINARYTREE_CPP
#include "RootedBinaryTree.h"
template<class T>
void RootedBinaryTree<T>::copySubtree(Node<T> * & target, Node<T> * const & original)
{
// later add something here to delete a subtree if the node we are trying to assign to has children
// perhaps a deleteSubtree() method
target = new Node<T>;
if(original->leftChild != 0L)
{
copySubtree(target->leftChild, original->leftChild);
}
else
{
target->leftChild = 0L;
}
// ^^^ copy targets left (and right) children to originals
if(original->rightChild != 0L)
{
copySubtree(target->rightChild, original->rightChild);
}
else
{
target->rightChild = 0L;
}
target->nodeData = original->nodeData;
}
template <class T>
void RootedBinaryTree<T>::deleteSubtree(Node<T> * n) // Done
{// Assumes that n is a valid node.
if(n->leftChild != 0L) deleteSubtree(n->leftChild); // Delete all nodes in left subtree
if(n->rightChild != 0L) deleteSubtree(n->rightChild); // Delete all nodes in right subtree
delete n;
}
template <class T>
RootedBinaryTree<T>::RootedBinaryTree(const T & rootData) // Done
{
root = new Node <T>;
root->leftChild = 0L;
root->rightChild = 0L;
root->nodeData = rootData;
currentPosition = root;
}
template <class T>
RootedBinaryTree<T>::RootedBinaryTree(const RootedBinaryTree<T> & original)
{
}
template <class T>
RootedBinaryTree<T>::~RootedBinaryTree()
{
deleteSubtree(root); // root will be valid because of our constructor and other methods
root = currentPosition = 0L;
}
template <class T>
void RootedBinaryTree<T>::toRoot() // Done
{
currentPosition = root;
}
template <class T>
bool RootedBinaryTree<T>::moveLeft() // Done
{
if(currentPosition->leftChild == 0L) return false;
currentPosition = currentPosition->leftChild;
return true;
}
template <class T>
bool RootedBinaryTree<T>::moveRight() // Done
{
if(currentPosition->rightChild == 0L) return false;
currentPosition = currentPosition->rightChild;
return true;
}
template <class T>
RootedBinaryTree<T> & RootedBinaryTree<T>::operator=(const RootedBinaryTree<T> & RHS)
{
}
template <class T>
void RootedBinaryTree<T>::combineTrees(const RootedBinaryTree<T> & leftTree, const RootedBinaryTree<T> & rightTree)
{ // Copies leftTree into root's left tree and rightTree into root's right tree.
if(root->leftChild != 0L) deleteSubtree(root->leftChild);
if(root->rightChild != 0L) deleteSubtree(root->rightChild);
copySubtree(root->leftChild, leftTree.root);
copySubtree(root->rightChild, rightTree.root);
}
template <class T>
void RootedBinaryTree<T>::setNodeData(const T & nodeData)
{
currentPosition->nodeData = nodeData;
}
#endif
Еще раз спасибо!
http://stackoverflow.com/questions/1143262/what-is-the-difference-between-const-int-const-int-const-int-const –
Вы должны знать, что «до типа данных» язык, предлагаемый для визуальной ясности: 'const Тип var' и' Type const var' являются синонимами. Синтаксис становится более интересным, когда вы начинаете бросать указатели и ссылки в микс. 'const Тип * var' и' Тип const * var', например – WhozCraig
После прочтения ответа на ссылку Retired Ninja я думаю, что понимаю, в чем разница, но я все еще не уверен, что это то, что я хочу в своем коде. I.e., я знаю, что он строит, но вызовет ли это проблемы во время выполнения? – Tom