Недостатки прямого объявления класса C ++? - PullRequest
12 голосов
/ 10 августа 2009

Я хочу использовать предварительное объявление класса в моем программном обеспечении, чтобы я мог иметь typedefs
и использовать их внутри полной декларации класса.

Что-то вроде этого:

class myclass;
typedef boost::shared_ptr<myclass> pmyclass;
typedef std::list<pmyclass > myclasslist;

class myclass : public baseclass
{
private:        // private member declarations
        __fastcall myclass();

public:         // public member declarations
        __fastcall myclass(myclass *Parent)
            : mEntry(new myclass2())
          {
            this->mParent = Parent;
          }
        const myclass *mParent;
        myclasslist mChildren;
        boost::scoped_ptr<myclass2> mEntry;
};

поэтому мой вопрос: есть ли недостатки в этом методе? Я вспоминаю некоторые обсуждения проблем деструкторов с предварительным объявлением, но я не получил все оттуда.
или есть какой-то другой способ реализовать что-то подобное?

Спасибо.

EDIT: Я нашел обсуждение, на которое я ссылался: здесь

Ответы [ 2 ]

22 голосов
/ 10 августа 2009

Главный недостаток - все. Форвардные объявления являются компромиссом для экономии времени компиляции и позволяют иметь циклические зависимости между объектами. Однако стоимость заключается в том, что вы можете использовать тип только в качестве ссылок и ничего не можете сделать с этими ссылками. Это означает, что нет наследования, нет передачи его как значения, нет использования вложенного типа или typedef в этом классе и т. Д. Это все большие недостатки.

Конкретная проблема уничтожения, о которой вы говорите, заключается в том, что если вы только перенаправляете объявление типа и удаляете его только в модуле, поведение не определено и ошибка не выдается.

Например:

class A;

struct C 
{
    F(A* a)
    {
        delete a;  // OUCH!
    }
}

Microsoft C ++ 2008 не вызывает деструктор и выдает следующее предупреждение:

warning C4150: deletion of pointer to incomplete type 'A'; no destructor called
             : see declaration of 'A'

Таким образом, вы должны быть начеку, что не должно быть проблемой, если вы воспринимаете предупреждения как ошибки.

5 голосов
/ 10 августа 2009

Из стандарта C ++:

5.3.5 / 5:

"Если удаляемый объект имеет неполный тип класса в точке удаление и полный класс имеет нетривиальный деструктор или функция освобождения, поведение не определено. "

...