'const' 문제의 C++ 배치.
-
21-12-2019 - |
문제
우선 이 질문에 답변해주신 모든 분들께 미리 감사의 말씀을 전하고 싶습니다.귀하의 도움에 크게 감사드립니다.처음으로 글을 올리게 되므로 예의에 어긋나는 글을 올려도 양해해 주시기 바랍니다.
내 질문은 메소드 프로토타입에 관한 것입니다.
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
다시 한 번 감사드립니다!
해결책
규칙은 다음과 같습니다 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
이 규칙 때문입니다.