何时使用参考会员?

时间:2013-10-25 10:49:38

标签: c++ reference member

我刚刚意识到我甚至无法弄清楚C ++中引用成员的一个用例。比如说,如果我定义以下类:

class Book {
   public:
       Book(const Author& author) : author(author) {}
   private:
       const Author &author;
}

我怎么能用呢?如果我将new ed Author传递给它:

Book book(*(new Author()));

它不会泄漏内存吗? Author什么时候会被释放?

让我再试一次。如何将局部变量传递给它:

Book macBook() {
    Author author();
    return Book(author);
}

返回的图书是否包含无效(已发布)参考?

我无法想象使用它的第三种方式。那么为什么参考成员存在?我什么时候应该使用它?

编辑:我知道有share_ptr。但我是否总是希望share_ptr参考?

3 个答案:

答案 0 :(得分:3)

你必须确保作者的一生至少和书一样长(或者至少要小心不要在作者的一生之外使用本书的参考)。确保这一点的一种简单方法是将它们放在同一范围内,首先创建作者:

Author author;
Book book(author);

正如你所说,问题中的两个例子都很糟糕:第一个泄漏内存(或者,如果你添加了一个*来进行编译),第二个会给你一个悬空引用。但是还有很多其他方法来管理对象的生命周期。

答案 1 :(得分:2)

如果您的功能需要const Author&并且您传递new Author(),那么您的程序将无法编译,因为new Author()Author*,而不是Author& }。

您可以传递*(new Author()),但除非Book的析构函数删除&author,否则您将会泄密。但是,拥有一个引用成员并在析构函数中获取该成员的地址并delete它是非常奇怪的。你的开发人员会讨厌你,尤其是因为函数签名不清楚,必须使用new来分配参数。

您可以将Author传递给Book(const Author& author),但必须确保Author至少和Book一样长。是的,在代码中

Book macBook() {
    Author author();
    return Book(author);
}

退回的图书无效参考。

我怀疑引用成员存在的原因与存在空指针的原因相同:因为它很容易实现。

答案 2 :(得分:1)

如果按值复制对象的代价很​​高,则通常引用很有用。如果将对象作为参数传递给函数,并且复制它的代价很高,则需要使用引用。当然,如果您不打算通过函数修改对象,您实际上将使用常量引用:

void someFunc(const BigObject& object)
{
    /* 'object' is used here */
}

现在一个类构造函数是“只是另一个函数”,所以我们可以在这里使用相同的模式:如果你想提供一个复制到某个类实例的昂贵的对象,以便在其生命周期内使用 ,在该类中定义一个const-ref成员是有意义的,该成员将绑定到类构造函数中提供的对象:

class Worker
{
public:
    Worker(const BigObject& object) : m_object(object) { /* ... */ }
    // ...
private:
    const BigObject& m_object;
}

BigObject object;
Worker worker(object);

当然,这里要记住的最重要的事情是确保BigObject对象存在时Worker对象不会被销毁。 (在上面的示例中,这是正常的,因为两个变量都是自动的。)

当然,可以使用指针代替引用来实现相同的效果,但是使用指针时,总是必须考虑指针为零(有意或无意)的情况,并且需要明确使用{ {1}}运算符传递对象,因此引用版本只是使代码更简单。