通过构造函数传递的引用定义 class 成员
Defining class member via a reference passed through constructor
我正在使用 C++ 实现链表,我对原始数据的生命周期很好奇。假设一个调用程序使用以下构造函数创建一个新的 ListNode。我担心的是,如果数据成员分配不是值的副本,则原始变量可能会很好地超出范围而留下未定义的行为。
ListNode<T>::ListNode(const T &value) : data(value) {}
当将值传递给参数列表中的数据时,它会将数据定义为值的副本还是将 class 成员链接到传递给构造函数的原始变量?
编辑:为清楚起见添加更多信息
list_node.hpp
template <typename T>
class ListNode
{
friend class List<T>;
public:
ListNode<T>(const T &);
private:
T data;
};
list.hpp
template<typename T>
class List
{
public:
void insert_at_front(const T &);
private:
ListNode<T> *get_new_node(const T &);
};
list.cpp
void List<T>::insert_at_front(const T &value)
{
ListNode<T> *new_node_ptr = get_new_node(value);
...
}
ListNode<T> *List<T>::get_new_node(const T &value)
{
return new ListNode<T>(value);
}
struct Foo {
Foo(const Bar& b) : m_b(b) {}
Bar m_b;
};
struct Foo2 {
Foo2(const Bar& b) : m_b(b) {}
const Bar& m_b;
};
如您所见,构造函数代码是相同的,但这两个 classes 做了一些不同的事情。第一个 class 将复制传递的 Bar
,因此如果传入的局部变量超出范围,则为 "safe"。第二个 class 只是获取引用。实际上,这就像持有对传入变量的引用。因此,如果传入的变量超出范围,则 Foo2
将有一个悬空引用。
我正在使用 C++ 实现链表,我对原始数据的生命周期很好奇。假设一个调用程序使用以下构造函数创建一个新的 ListNode。我担心的是,如果数据成员分配不是值的副本,则原始变量可能会很好地超出范围而留下未定义的行为。
ListNode<T>::ListNode(const T &value) : data(value) {}
当将值传递给参数列表中的数据时,它会将数据定义为值的副本还是将 class 成员链接到传递给构造函数的原始变量?
编辑:为清楚起见添加更多信息
list_node.hpp
template <typename T>
class ListNode
{
friend class List<T>;
public:
ListNode<T>(const T &);
private:
T data;
};
list.hpp
template<typename T>
class List
{
public:
void insert_at_front(const T &);
private:
ListNode<T> *get_new_node(const T &);
};
list.cpp
void List<T>::insert_at_front(const T &value)
{
ListNode<T> *new_node_ptr = get_new_node(value);
...
}
ListNode<T> *List<T>::get_new_node(const T &value)
{
return new ListNode<T>(value);
}
struct Foo {
Foo(const Bar& b) : m_b(b) {}
Bar m_b;
};
struct Foo2 {
Foo2(const Bar& b) : m_b(b) {}
const Bar& m_b;
};
如您所见,构造函数代码是相同的,但这两个 classes 做了一些不同的事情。第一个 class 将复制传递的 Bar
,因此如果传入的局部变量超出范围,则为 "safe"。第二个 class 只是获取引用。实际上,这就像持有对传入变量的引用。因此,如果传入的变量超出范围,则 Foo2
将有一个悬空引用。