Бьерн Страуструп.
Язык программирования С++
320
[2]
Описать член типа X* или X&.
Если значение указателя не будет меняться и вопросы эффективности не волнуют, эти способы
эквивалентны:
class X {
//...
public:
X(int);
//...
};
class C {
X
a;
X*
p;
public:
C(int i, int j) : a(i), p(new X(j)) { }
~C() { delete p; }
};
В
таких ситуациях предпочтительнее непосредственное членство объекта, как X::a в примере выше,
потому что оно дает экономию времени, памяти и количества вводимых символов. Обратитесь также к
$$12.4 и $$13.9.
Способ, использующий указатель, следует применять в
тех случаях, когда приходится перестраивать
указатель на "объект-элемент" в течении жизни "объекта-владельца". Например:
class C2 {
X*
p;
public:
C(int i) : p(new X(i)) { }
~C() { delete p; }
X*
change(X*
q)
{
X*
t
=
p;
p
=
q;
return
t;
}
};
Член типа указатель может также использоваться, чтобы дать возможность передавать "объект-
элемент" в качестве параметра:
class C3 {
X*
p;
public:
C(X* q) : p(q) { }
//
...
}
Разрешая объектам содержать указатели на другие объекты, мы создаем то, что обычно называется
"иерархия объектов". Это альтернативный и вспомогательный способ структурирования по отношению к
иерархии классов. Как было показано на примере аварийного движущегося средства в $$12.2.2, часто
это довольно тонкий
вопрос проектирования: представлять ли свойство класса как еще один базовый
класс или как член класса. Потребность в переопределении следует считать указанием, что первый
вариант лучше. Но если надо иметь возможность представлять некоторое свойство с
помощью
различных типов, то лучше остановиться на втором варианте. Например:
class XX : public X { /*...*/ };
class XXX : public X { /*...*/ };
void f()
{
Бьерн Страуструп.
Язык программирования С++
321
C3* p1 = new C3(new X); // C3 "
содержит" X
C3* p2 = new C3(new XX); // C3 "содержит" XX
C3* p3 = n
ew C3(new XXX); // C3 "содержит" XXX
//...
}
Приведенные определения нельзя смоделировать ни с помощью производного класса C3 от X, ни с
помощью C3, имеющего член типа X, поскольку необходимо указывать точный тип члена. Это важно
для классов с
виртуальными функциями, таких, например,как класс Shape ($$1.1.2.5), и для класса
абстрактного множества ($$13.3).
Заметим, что ссылки можно применять для упрощения классов, использующих члены-указатели, если в
течение жизни объекта-владельца ссылка настроена только на один объект, например:
class C4 {
X& r;
public:
C(X& q) : r(q) { }
//
...
};
Достарыңызбен бөлісу: