Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Указатель вместо ссылки в private-секции.


Автор: kemiisto 7.3.2010, 00:49
Вообщем вот что. Все мы знаем, что в public интерфейсе (С++ класса) лучше использовать ссылки, а не указатели. Ссылки - везде, где это возможно, указатели - только в случае необходимости.

Но последнее время у меня возникает стойкое желание использовать ссылки не только "снаружи", но и "внутри".

Пример:
Код

class MainWindow: public QMainWindow
{
  Q_OBJECT

public:
  ...

private:
  Render::Viewer& viewer();
  Render::Viewer* viewer_;
  ...
}


В итоге в методе класса ("внутри") вместо
Код
viewer_->fileMol().generate()

пишем
Код
viewer().fileMol().generate()


Как-то красивше. Единообразный стиль...

Кто что думает?

Автор: andrew_121 7.3.2010, 00:53
т.е. у вас это реализовано так:
Код

Render::Viewer& viewer() {
   return *viewer_;
}

?

up

Автор: mes 7.3.2010, 01:12
Цитата(kemiisto @  6.3.2010,  23:49 Найти цитируемый пост)
Ссылки - везде, где это возможно, указатели - только в случае необходимости.

тут несколько другое правило: ссылка если объект "всегда есть" и указатель если "может быть нулем".

Цитата(kemiisto @  6.3.2010,  23:49 Найти цитируемый пост)
В итоге в методе класса ("внутри") вместо

разгрузка через функцию всегда хорошо.. т.е.  чем меньше прямых связей с переменной тем лучше.

Цитата(kemiisto @  6.3.2010,  23:49 Найти цитируемый пост)
Как-то красивше.

и не только красиво, но и больше свободы smile

Добавлено через 1 минуту и 36 секунд
Цитата(kemiisto @  6.3.2010,  23:49 Найти цитируемый пост)
что в public интерфейсе (С++ класса) 

имхо не правильный акцент на "public " 

Автор: andrew_121 7.3.2010, 01:14
Цитата(kemiisto @  7.3.2010,  00:49 Найти цитируемый пост)
Но последнее время у меня возникает стойкое желание использовать ссылки не только "снаружи", но и "внутри".

Код

class MainWindow: public QMainWindow
{
  Q_OBJECT
public:
   MainWindow(...):viewer(Render::Viewer(...)) {}
  ...
private:
  Render::Viewer& viewer;
  ...
}


Автор: kemiisto 7.3.2010, 02:02
Цитата(andrew_121 @  7.3.2010,  01:53 Найти цитируемый пост)
т.е. у вас это реализовано так:

Угу. smile 

Цитата(mes @  7.3.2010,  02:12 Найти цитируемый пост)
тут несколько другое правило: ссылка если объект "всегда есть" и указатель если "может быть нулем".

Да, да. Именно это я и имел ввиду.

Цитата(mes @  7.3.2010,  02:12 Найти цитируемый пост)
разгрузка через функцию всегда хорошо.. т.е.  чем меньше прямых связей с переменной тем лучше.

Собственно, в этом и был вопрос. Просто хотел удостовериться.

andrew_121, так тоже можно. Но невсегда. Иногда ведь нужно иметь возможность заNULLить. smile 

Автор: mes 7.3.2010, 02:11
Цитата(kemiisto @  7.3.2010,  01:02 Найти цитируемый пост)
Иногда ведь нужно иметь возможность заNULLить.

или просто поменять объект.

Автор: Alek86 7.3.2010, 09:56
andrew_121, что в твоем коде получится? ссылка на временный обьект?

Автор: andrew_121 7.3.2010, 16:09
Alek86, да, все верно. smile

Добавлено через 4 минуты и 36 секунд
вопрос.
такой код:
Код

class MainWindow: public QMainWindow {
public:
    MainWindow(QWidget* parent = 0):dialog(QDialog(parent)) {}
    QDialog& dialog;
};

компилятор ругается:
Цитата

ошибка: invalid initialization of non-const reference of type ‘QDialog&’ from an rvalue of type ‘QDialog’


но если ссылка константная:
Код

class MainWindow: public QMainWindow {
public:
    MainWindow(QWidget* parent = 0):dialog(QDialog(parent)) {}
    const QDialog& dialog;
};

то все ок.
почему так?

Автор: Alek86 7.3.2010, 16:30
в стардарте явно прописано, что в случае, когда временный обьект возвращается в константную ссылку, его жизнь продолжается до того момента, пока не уничтожится эта самая ссылка
но у меня ощущение, что это правило работает только для ссылок-переменных в функциях, и не уверен что твой временный QDialog должен жить до вызова деструктора MainWindow. Возможно то, что не пишется ошибка - бага компилятора

а зачем так извращаться? напиши просто:

Код
class MainWindow: public QMainWindow {
public:
    MainWindow(QWidget* parent = 0):dialog(parent) {}
    QDialog dialog;
};

Автор: andrew_121 7.3.2010, 16:48
Цитата(Alek86 @  7.3.2010,  16:30 Найти цитируемый пост)
не уверен что твой временный QDialog должен жить до вызова деструктора MainWindow.

но работает.

Цитата(Alek86 @  7.3.2010,  16:30 Найти цитируемый пост)
Возможно то, что не пишется ошибка - бага компилятора

хз. в наличии gcc-4.5.0. не самый бажный компилятор.

Цитата(Alek86 @  7.3.2010,  16:30 Найти цитируемый пост)
а зачем так извращаться?

это вопрос к kemiisto)

Автор: mes 7.3.2010, 17:12
Цитата(andrew_121 @  7.3.2010,  15:48 Найти цитируемый пост)
но работает.


Цитата

12.2 Temporary objects
There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression.
 The first context is when an expression appears as an initializer for a declarator defining an
object.... 
 The second context is when a reference is bound to a temporary. The temporary to which the reference is
bound or the temporary that is the complete object to a subobject of which the temporary is bound persists
for the lifetime of the reference except as specified below. A temporary bound to a reference member in a
constructor’s ctor-initializer (12.6.2) persists until the constructor exits. 
A temporary bound to a reference
parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.
A temporary bound to the returned value in a function return statement (6.6.3) persists until the function
exits. In all these cases, the temporaries created during the evaluation of the expression initializing the reference,
except the temporary to which the reference is bound, are destroyed at the end of the full-expression
in which they are created and in the reverse order of the completion of their construction.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)