Члены класса, которые являются объектами - указатели или нет? C ++ - PullRequest
36 голосов
/ 06 октября 2010

Если я создаю класс MyClass и в нем есть какой-то закрытый член, скажем, MyOtherClass, лучше сделать указатель MyOtherClass или нет? Что значит также иметь его как не указатель с точки зрения того, где он хранится в памяти? Будет ли объект создан при создании класса?

Я заметил, что примеры в QT обычно объявляют члены класса как указатели, когда они являются классами.

Привет

Mark

Ответы [ 11 ]

0 голосов
/ 06 октября 2010

Самое простое, что нужно сделать - это объявить своих членов объектами. Таким образом, вам не нужно заботиться о копировании, уничтожении и назначении. Об этом все позаботятся автоматически.

Тем не менее, есть некоторые случаи, когда вам нужны указатели. В конце концов, управляемые языки (такие как 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 и умные указатели (здесь и где-то еще в Интернете много ресурсов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...