3

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

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

我怎么可能使用它?如果我将newed传递Author给它:

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

它不会泄漏内存吗?什么时候Author发布?

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

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

返回的书没有无效(已发布)引用吗?

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

编辑:我知道有share_ptr。但我应该总是更喜欢share_ptr参考吗?

4

3 回答 3

3

如果您的函数需要 aconst Author&并且您传递了 a new Author(),那么您的程序将无法编译,因为new Author()是 a Author*,而不是Author&

您可以传递 a *(new Author()),但除非析构函数Book删除&author. 但是,有一个引用成员并在析构函数中获取该成员的地址和它是非常奇怪的delete。你的开发人员会因此而讨厌你,特别是因为从函数签名中不清楚,参数必须使用new.

你可以通过一个Authorto Book(const Author& author),但你必须确保Author生命至少和the一样长Book。所以是的,在代码中

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

退回的书的参考文献无效。

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

于 2013-10-25T10:58:52.610 回答
3

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

Author author;
Book book(author);

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

于 2013-10-25T10:55:29.087 回答
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。(在上面的示例中,这是可以的,因为这两个变量都是自动的。)

当然,可以使用指针代替引用来实现相同的效果,但是对于指针,人们总是必须考虑指针为零(有意或无意)的情况,并且需要显式使用&运算符来传递对象,所以参考版本只是使代码更简单。

于 2013-10-25T11:46:44.973 回答