C++: auto_ptr + предописание?

У меня есть класс как это:

class Inner;

class Cont
{
public:
    Cont();
    virtual ~Cont();
private:
    Inner* m_inner;
};

в .cpp конструктор создает экземпляр Inner с new и деструктор deletes это. Это работает вполне прилично.
Теперь я хочу изменить этот код для использования auto_ptr таким образом, я пишу:

class Inner;

class Cont
{
public:
    Cont();
    virtual ~Cont();
private:
    std::auto_ptr<Inner> m_inner;
};

Теперь, конструктор, инициализированный auto_ptr и деструктор ничего не делает.

Но это не работает. проблема, кажется, возникает, когда я инстанцирую этого класса. Я получаю это предупреждение:

предупреждение C4150: удаление указателя на неполный 'Внутренний' тип; никакой деструктор не называют

Ну, это очевидно очень плохо, и я понимаю, почему это происходит, компилятор не знает о d'tor Inner при инстанцировании шаблона auto_ptr<Inner>

Так мой вопрос: Есть ли способ использовать auto_ptr с предописанием как я сделал в версии, которая использует просто указатели?
Необходимость к #include каждый класс, на который я объявляю указатель, является огромной стычкой и время от времени, просто невозможный. Как эта проблема обычно решается?

12
задан trompa 28 February 2014 в 15:54
поделиться

4 ответа

Вам необходимо включить заголовок, определяющий класс Inner , в файл, где Находится реализация Cont :: ~ Cont () . Таким образом, у вас все еще есть предварительное объявление в заголовке, определяющем class Cont , и компилятор видит определение внутреннего класса и может вызвать деструктор.

//Cont.h
class Inner; // is defined in Inner.h
class Cont 
{ 
    virtual ~Cont(); 
    std::auto_ptr<Inner> m_inner;
};

// Cont.cpp
#include <Cont.h>
#include <Inner.h>

Cont::~Cont()
{
}
13
ответ дан 2 December 2019 в 06:08
поделиться

Этот вопрос (удаление объекта с помощью частного деструктора) и этот вопрос (как написать iscomplete шаблон) могут вам помочь.

0
ответ дан 2 December 2019 в 06:08
поделиться

Вместо этого вы можете использовать boost :: shared_ptr (). У него нет практических недостатков вместо производительности, и он гораздо более удобен для пересылки объявлений:

boost :: shared_ptr ptr;

в порядке, без дополнительных объявлений выше.

shared_ptr делает больше, чем auto_ptr , например подсчет ссылок, но это не должно повредить, если вам это не нужно.

3
ответ дан 2 December 2019 в 06:08
поделиться

Технически вы не должны создавать экземпляры стандартных библиотечных шаблонов с неполными типами, хотя я не знаю ни одной реализации, где это не сработает. На практике я бы порекомендовал и Sharptooth.

На самом деле нет ничего плохого в использовании открытого указателя для указателя на impl, если вы вызываете для него delete в своем деструкторе. Вероятно, вам также следует реализовать или отключить конструктор копирования и оператор присваивания.

0
ответ дан 2 December 2019 в 06:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: