通过参考问题

Pass By Reference Questions

本文关键字:问题 参考      更新时间:2023-10-16

我对按引用传递相当陌生,我必须确保我正确理解了这一点。我必须将所有堆内存转换为堆栈内存,因为我的教授是这么说的,我被困在两个概念上。

在类中存储引用的最佳方法是什么?我最初将成员对象作为非指针,但注意到当对象(不是成员对象)从堆栈中弹出时,将在成员变量上调用解构函数。这让我觉得这是一个副本,而不是一个参考。

这是我最初拥有的示例:

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&. 
对象

1 是副本还是实际上是对象 2 的另一个标识符?

引用的行为类似于实例的符号别名,并且在某些方面类似于不能(不应该)为空的"指针"。为了这个解释,我将在下面引用它们,就好像它们是指针一样。

当你有一个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&)时,在某些情况下,编译器可以省略它。例如:当这样的函数被内联时,引用可以替换为比要求它们为指针更有效的寻址逻辑。

在这方面,它们不是指针。