Самое простое — объявить членов как объекты. Таким образом, вам не нужно заботиться о создании, уничтожении и присвоении копий. Обо всем этом позаботятся автоматически.
Однако бывают случаи, когда вам нужны указатели. В конце концов, управляемые языки (такие как C# или Java) фактически содержат объекты-члены с помощью указателей.
Самый очевидный случай — это когда объект, который нужно сохранить, полиморфен. В Qt, как вы указали, большинство объектов принадлежат огромной иерархии полиморфных классов, и удержание их указателями является обязательным, поскольку вы заранее не знаете, какой размер будет иметь объект-член.
Пожалуйста, остерегайтесь некоторых распространенных ловушек в этом случае, особенно когда вы имеете дело с универсальными классами. Безопасность исключений является большой проблемой:
struct Foo
{
Foo()
{
bar_ = new Bar();
baz_ = new Baz(); // If this line throw, bar_ is never reclaimed
// See copy constructor for a workaround
}
Foo(Foo const& x)
{
bar_ = x.bar_.clone();
try { baz_ = x.baz_.clone(); }
catch (...) { delete bar_; throw; }
}
// Copy and swap idiom is perfect for this.
// It yields exception safe operator= if the copy constructor
// is exception safe.
void swap(Foo& x) throw()
{ std::swap(bar_, x.bar_); std::swap(baz_, x.baz_); }
Foo& operator=(Foo x) { x.swap(*this); return *this; }
private:
Bar* bar_;
Baz* baz_;
};
Как видите, довольно громоздко иметь безопасные для исключений конструкторы при наличии указателей. Вы должны взглянуть на RAII и интеллектуальные указатели (есть много ресурсов здесь и где-то еще в Интернете).
person
Alexandre C.
schedule
06.10.2010