Domanda

Prima di tutto vorrei ringraziare in anticipo chiunque risponda a questa domanda. Il tuo aiuto è molto apprezzato. Questa è la mia prima volta che posti qui, quindi per favore perdonami se postsi con cattiva etichetta.

La mia domanda riguarda il metodo prototipo:

void copySubtree(Node<T> * & target, Node<T> * const & original);
.

E quando chiamo copySubtree() in seguito in combineTrees(). Come è attualmente il codice, si basa. Ma quello che originariamente aveva era:

void copySubtree(Node<T> * & target, const Node<T> * & original);
.

che mi ha dato l'errore:

error C2664: 'RootedBinaryTree<T>::copySubtree' : cannot convert parameter 2 from 'RootedBinaryTree<T>::Node<T> *const ' to 'const RootedBinaryTree<T>::Node<T> *&'
.

So che quando metti const prima del tipo di dati nel parametro ti impedisce di modificare detto parametro nel tuo metodo, ma non so cosa lo fa quando lo metti dopo il tipo di dati, né lo sono certo Il mio codice si è costruito con il posizionamento di const dopo che il tipo di dati non era solo un colpo di fortuna. Cosa fa posizionare const dopo che un tipo di dati fa? Il mio codice ha problemi di runtime orribili nel modo in cui è attualmente scritto?

[anche: sono nel processo di tentativo di scrivere le definizioni del metodo del modello di classe Binary Tree Binary (motivo per cui alcuni dei metodi sono vuoti e ci sono alcune note casuali a me stesso nei commenti). Quindi mi scuso per qualsiasi inconveniente causato da quello.]

Ecco il codice pertinente:

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
.

Grazie ancora!

È stato utile?

Soluzione

La regola è che const si attacca alla cosa sulla sua sinistra, e se non c'è niente a sinistra, si attacca alla cosa a destra.Quindi in questo caso, abbiamo:

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
.

La maggior parte delle persone scrive const Type, perché è così che tendiamo a pensare a loro, ma alcune persone preferiscono scrivere generacoli Type const a causa di questa regola.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top