在课堂上传递参考

时间:2011-04-12 12:00:23

标签: c++ class reference types linked-list

我完全糊涂了。在这个属于我班级的例子中,我有:

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

这意味着fValueconst DataType*,现在我希望通过此部分将stringint等数据类型应用/定义到fValue:< / p>

    DoubleLinkedNode( const DataType& aValue ){

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

我很困惑,我必须在那里写什么以及为什么?如何定义aValuefValue? (注意:std::cout << " -- " << aValue << std::endl;仅用于测试)

3 个答案:

答案 0 :(得分:2)

我不太确定你在这里尝试做什么,但是如果你想用fValue指向aValue的地址(通过引用传递给构造函数)来构造DoubleLinkedNode,你需要定义你的构造函数方式:

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 :(得分:1)

由于fValue是指针,而DoubleLinkedNode()通过引用获取对象,因此需要取消引用指针,如下所示:

DoubleLinkedNode(*fValue);

答案 2 :(得分:1)

如果fValue是指针,则需要指向其他地方创建的某个变量。那么什么代码负责指向值*fValue的生命周期?

如果类需要自己创建值并且fValue确实需要成为指针,则可以使用newdelete

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)
{}