2013-10-25 3 views
2

Я только что понял, что даже не могу определить один вариант использования ссылочного элемента в C++. Скажем, если я определю следующий класс:Когда использовать ссылочный элемент?

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

Как я мог его использовать? Если я прохожу new ред Author к нему:

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

Не это утечка памяти? Когда выйдет Author?

Позвольте мне попробовать еще раз. Как насчет прохождения с ней локальной переменной:

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

Не вернули ли возвращенную книгу недопустимую ссылку?

Я не могу представить себе третий способ его использования. Итак, почему существует ссылочный член? Когда я должен его использовать?

EDIT: Я знаю, что есть 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 urally, самое главное иметь в виду здесь, чтобы убедиться, что объект BigObjectне разрушен, а объект Worker существует. (В приведенном выше примере это нормально, потому что обе переменные являются автоматическими.)

Конечно, вместо ссылки можно использовать указатель для достижения такого же эффекта, но с указателями всегда нужно думать о случае, когда указатель (преднамеренно или случайно), и необходимо явно использовать оператор & при передаче объекта, поэтому эталонная версия просто упрощает код.

Смежные вопросы