سؤال

في البداية أود أن أشكر مقدما كل من يجيب على هذا السؤال.مساعدتكم هو موضع تقدير كبير.هذه هي المرة الأولى التي أنشر فيها هنا، لذا أرجو أن تسامحوني إذا نشرت بطريقة سيئة.

سؤالي يتعلق بالنموذج الأولي للطريقة:

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 بسبب هذه القاعدة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top