2013-10-25 47 views
2

我剛剛意識到我甚至無法弄清楚C++中引用成員的一個用例。說,如果我定義以下類:何時使用引用成員?

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

我怎麼能使用它?如果我通過一個newAuthor它:

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

不會造成內存泄露? Author什麼時候發佈?

讓我再試一次。如何通過一個本地變量:

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

不是返回的書有一個無效的(釋放)參考嗎?

我無法想象使用它的第三種方法。那麼爲什麼參考成員存在?我應該什麼時候使用它?我想知道有share_ptr。但我應該總是喜歡share_ptr參考?

+0

只要確保它會超過引用,即保存引用的對象的實例,就可以初始化對象的引用,而不管它如何分配。 – thokra

回答

3

您必須確保作者的生命至少與書一樣長(或至少非常小心,不要在作者生命期之外使用書的參考)。一個簡單的方法,以確保是把他們在相同的範圍內,與筆者第一次創建:

Author author; 
Book book(author); 

正如你所說的,無論是在問題的例子是不好的:第一是存在內存泄漏(或者假使你添加了一個*來編譯它),第二個讓你留下一個懸而未決的參考。但是還有很多其他的方式來管理對象的生命週期。

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); 
} 

返回的書有一個無效的參考。

我懷疑引用成員的存在與空指針存在的原因相同:因爲它很容易實現。

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); 

Nat在這裏,最重要的是要確保BigObject對象不會被破壞Worker對象存在。 (在上面的例子中,這是可以的,因爲兩個變量都是自動的。)

當然,可以使用指針代替引用來達到相同的效果,但指針總是必須考慮指針是零(有意或無意),並且需要在傳遞對象時明確使用&運算符,因此引用版本只是簡化了代碼。