Как вы инициализируете защищенные члены абстрактного базового класса? - PullRequest
1 голос
/ 27 февраля 2012

Возможно, я ни о чем не беспокоюсь.Я желаю, чтобы члены данных следовали идиоме RAIIКак я могу инициализировать член защищенного указателя в абстрактном базовом классе как нулевой?

Я знаю, что это должно быть нулевым, но разве не было бы лучше обеспечить универсальное понимание?

код инициализации вне списка инициализатора может быть не запущен.Думая с точки зрения операций сборки для размещения этого указателя на стеке, разве они не могут быть прерваны почти таким же образом (как тело c'tor) в многопоточных средах или гарантируется, что расширение стека будет атомарным?Если деструктор гарантированно будет работать, то разве у расширения стека не будет такой гарантии, даже если процессор не выполнит его атомарно?

Как такой простой вопрос стал настолько обширным?Спасибо.

Если бы я мог избежать std :: library, это было бы здорово, я нахожусь в минимилистской среде.

Ответы [ 2 ]

3 голосов
/ 27 февраля 2012

Возможно, ты слишком обдумываешь это. В следующем примере базовый член инициализирован нулем:

struct Base
{
    virtual ~Base() = 0; // or make something else pure; this is just an example

    Base() : p() { }           // p initialized to null
    Base(Foo * q) : p(q) { }   // another option

protected:
     Foo * p;
};

struct Derived : private Base
{
    // no extra work needed

    // maybe something like this...
    Derived(int a, bool c) : Base(new Foo(a * (c ? 2 : 3))) { }
};

Производный конструктор сначала вызывает базовый конструктор, а тот, в свою очередь, говорит, что Base::p инициализируется нулем.

3 голосов
/ 27 февраля 2012

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

class base{
public:
    base() : a(new int(5)) {}
protected:
    std::unique_ptr<int> a;
    virtual ~base() {} 
};

class child : public base {
     child() : base() {}
     ~child() {} //a will automatically be deleted
};

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

Другой способ - удалить его вручную в базовом деструкторе

class base{
public:
    base() : a(new int(5)) { }    //base member init'd
protected:
    int* a;
    virtual ~base() { delete a;  } //base member destroyed
};
...