我对按引用传递相当陌生,我必须确保我正确理解了这一点。我必须将我所有的堆内存转换为堆栈内存,因为我的教授是这样说的,而且我坚持两个概念。
在类中存储引用的最佳方式是什么?我最初将成员对象作为非指针,但注意到当对象(不是成员对象)从堆栈中弹出时,将在成员变量上调用解构函数。这让我觉得它是一个拷贝,而不是实际的引用。
这是我最初的例子:
class B
{
public:
B();
~B();
};
class A
{
private:
B b;
public:
A();
~A();
setB(B& bVar);
};
void A::setB(B& bVar)
{
b = bVar;
}
我的解决方案是将其更改为指针,这样它就不会调用解构函数,但我不确定这是否是正确的方法。这是我的解决方案:
class B
{
public:
B();
~B();
};
class A
{
private:
B* b;
public:
A();
~A();
setB(B& bVar);
};
void A::setB(B& bVar)
{
b = &bVar;
}
我的第二个问题有点相关。我不确定当您拥有以下内容时究竟会发生什么:
object1 = object2&.
object1 是一个拷贝还是实际上是 object2 的另一个标识符?
最佳答案
引用的行为类似于实例的符号别名,并且在某些方面类似于不能(不应该)为空的“指针”。为了便于解释,我将在下面将它们作为指针来引用。
当你有一个 T&
, 这意味着它指向一个 T
, 并且本身不是拷贝。
当你有一个 T = T&
,这意味着您将根据构造函数或赋值运算符的定义方式获得拷贝(或拷贝的拷贝)。
当你有一个 R& = L
,这意味着您将获得 L
的拷贝进入R&
指向(前提是 R
的赋值运算符允许这样做)。
关于存储引用的“正确”方式,我至少会问这些问题:
- 成员引用在包含对象的整个生命周期中保持不变是否可以接受?
- 包含类型的实例是否总是在成员引用指向的对象之前被销毁?
如果两者都为真,则只需声明并适本地初始化一个成员 T&
应该足够了:
class B
{
// details...
};
class A
{
B &_b;
public:
A(B &b) :
_b(b)
{}
};
否则,尽管对您提出了要求,但情况可能需要类似 shared_ptr<>
的内容或类似的。
对生活在堆栈中的对象的引用,反过来又被其他对象持有,这些对象本身可能以这样一种方式构造,它们将比其引用的生命周期更长,只是等待悬挂的指针。
考虑复制,或争论堆分配内存是更好的选择。
如果您不确定您的程序引入的引用网络,您需要重新设计它。
编辑:
重要的是要注意,在传递对函数的引用时(特别是 const T&
),在某些情况下它可能会被编译器忽略。例如:当这样的函数被内联时,引用可以被更高效的寻址逻辑替换,而不是它们被要求为指针时。
在这方面,它们不是指针。
关于c++ - 通过引用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19974658/