2013-11-18 4 views
0

Прежде всего, я хотел бы заранее поблагодарить любого, кто отвечает на этот вопрос. Ваша помощь очень ценится. Это моя первая публикация здесь, поэтому, пожалуйста, простите меня, если я напишу с плохим этикетом.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 

Еще раз спасибо!

+0

http://stackoverflow.com/questions/1143262/what-is-the-difference-between-const-int-const-int-const-int-const –

+0

Вы должны знать, что «до типа данных» язык, предлагаемый для визуальной ясности: 'const Тип var' и' Type const var' являются синонимами. Синтаксис становится более интересным, когда вы начинаете бросать указатели и ссылки в микс. 'const Тип * var' и' Тип const * var', например – WhozCraig

+0

После прочтения ответа на ссылку Retired Ninja я думаю, что понимаю, в чем разница, но я все еще не уверен, что это то, что я хочу в своем коде. I.e., я знаю, что он строит, но вызовет ли это проблемы во время выполнения? – Tom

ответ

2

Правило состоит в том, что const прикрепляется к предмету слева, а если ничего не находится слева, он присоединяется к предмету справа. Так что в данном случае мы имеем:

const Node *p; // p is a pointer to a const Node 
Node const *p; // same again, p is a pointer to a const Node 
Node * const p; // p is a const pointer to a (mutable) Node 
const Node * const p; // p is a const pointer to a const Node 
Node const * const p; // same again, p is a const pointer to a const Node 

Большинство людей пишут const Type, потому что, как мы склонны думать о них, но некоторые люди предпочитают писать Type const из этого правила.

+0

См. [Это (по общему признанию автору) диатриба] (http://stackoverflow.com/questions/14562845/c-expected-const-char-warning/14566215#14566215) на 'const 'расширения через два уровня косвенности. Его диаграмма helluva = P (моим фаворитом является 'char const * const * const p') – WhozCraig

+0

Спасибо! Теперь я понимаю. – Tom

Смежные вопросы