Передача Ссылка в классе - PullRequest
1 голос
/ 12 апреля 2011

Я полностью сбит с толку.В этом примере, который является частью моего класса, у меня есть:

public:
        typedef DoubleLinkedNode<DataType> Node;    
private:
            const DataType* fValue;
            Node* fNext;
            Node* fPrevious;
            DoubleLinkedNode(): fValue((const DataType*)0){
                fNext = (Node*)0;
                fPrevious = (Node*)0;
            }

Что означает fValue это const DataType*, теперь я хочу применить / определить тип данных, например string или intна fValue этой частью:

    DoubleLinkedNode( const DataType& aValue ){

        std::cout << "  --  "  << aValue << std::endl;
    }

Я запутался, что именно я должен написать там и почему?Как я могу определить aValue для моего fValue?!(примечание: std::cout << " -- " << aValue << std::endl; только для теста)

Ответы [ 3 ]

2 голосов
/ 12 апреля 2011

Я не совсем уверен, что вы пытаетесь сделать здесь, но если вы хотите создать DoubleLinkedNode с fValue, указывающим на адрес aValue (который был передан конструктору по ссылке), вам нужно определить свой конструктор следующим образом способ:

DoubleLinkedNode( const DataType& aValue ) : fValue(&aValue) {
        std::cout << "  --  "  << aValue << std::endl;
}

Обратите внимание, что это не на 100% безопасно, так как вы можете случайно вызвать этот конструктор со ссылкой rvalue (для упрощения: ссылка на объект, который уничтожается сразу после вызова функции) , Например, следующий код не вызовет ошибку компиляции:

std::string s = "Hello ";
DoubleLinkedNode<std::string> node = DoubleLinkedNode<std::string>(s + "World");

, хотя s + "World" - это временное значение, которое будет быстро уничтожено после вызова конструктора, и теперь fValue будет указывать на недопустимое расположение в памяти. Это очень плохо, так как вы не получите никаких предупреждений во время компиляции, но вы получите очень трудно отлаживаемое поведение во время выполнения.

Следовательно, может быть лучше создать конструктор, который ожидает указатели вместо ссылок:

DoubleLinkedNode( const DataType* aValue ) : fValue(aValue) {
        std::cout << "  --  "  << aValue << std::endl;
}
1 голос
/ 12 апреля 2011

Если fValue - указатель, он должен указывать на некоторую переменную, созданную в другом месте.Так какой код отвечает за время жизни указанного значения *fValue?

Если класс должен сам создать значение, а fValue действительно должен быть указателем, он может использовать newи delete:

template <typename DataType>
DoubleLinkedNode<DataType>::DoubleLinkedNode( const DataType& aValue )
  : fValue( new DataType(aValue) ), fNext(0), fPrevious(0)
{}
template <typename DataType>
DoubleLinkedNode<DataType>::~DoubleLinkedNode() {
    delete fValue;
}

Но я подозреваю, что дизайн мог бы работать лучше, если бы fValue не был указателем во-первых:

private:
    const DataType fValue;

// Requires a default constructor for DataType.
template <typename DataType>
DoubleLinkedNode<DataType>::DoubleLinkedNode()
  : fValue(), fNext(0), fPrevious(0)
{}
template <typename DataType>
DoubleLinkedNode<DataType>::DoubleLinkedNode( const DataType& aValue )
  : fValue(aValue), fNext(0), fPrevious(0)
{}
1 голос
/ 12 апреля 2011

Поскольку fValue является указателем, а DoubleLinkedNode () принимает объект по ссылке, вам необходимо разыменовать указатель, как показано ниже:

DoubleLinkedNode(*fValue);
...