Информация об изменениях

Сообщение Re[2]: Вопросы про novtable. default constructor. от 28.10.2019 10:00

Изменено 28.10.2019 10:08 rg45

Re[2]: Вопросы про novtable. default constructor.
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Интересно, а почему компилятор (VC) не позволяет запретить default-конструктор в классе с novtable и без каких-либо данных?


КД>
КД>class __declspec(novtable) t_myclass
КД>{
КД> public:
КД>  t_myclass()=delete;

КД>  virtual void method()=0;
КД>};
КД>


КД>При компиляции конструктора производного класса вылазит ошибка.

КД>Ответ я, собственно, знаю — потому что компилятор туповат.
КД>Но есть сомнения — может это я хочу странного?

Так novtable тут вообще ни при чем. Просто конструктор производного класса неявно использует конструктор по умолчанию базового класса, который у тебя запрещен. Чтобы избежать ошибки, нужно явно использовать какой-нибудь другой конструктор:

class __declspec(novtable) I
{
public:

    I() = delete;
    I(int) {}

    virtual void foo() = 0;
};

class B : public I
{
public:
    void foo() override {}

    B() : I(42) {}
};
Re[2]: Вопросы про novtable. default constructor.
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Интересно, а почему компилятор (VC) не позволяет запретить default-конструктор в классе с novtable и без каких-либо данных?


КД>
КД>class __declspec(novtable) t_myclass
КД>{
КД> public:
КД>  t_myclass()=delete;

КД>  virtual void method()=0;
КД>};
КД>


КД>При компиляции конструктора производного класса вылазит ошибка.

КД>Ответ я, собственно, знаю — потому что компилятор туповат.
КД>Но есть сомнения — может это я хочу странного?

Так novtable тут вообще ни при чем. Просто конструктор производного класса неявно использует конструктор по умолчанию базового класса, который у тебя запрещен. Чтобы избежать ошибки, нужно явно использовать какой-нибудь другой конструктор:

class __declspec(novtable) I
{
public:

    I() = delete;
    I(int) {}

    virtual void foo() = 0;
};

class B : public I
{
public:
    void foo() override {}

    B() : I(42) {}
};


P.S. Если тебе нужно только защититься от создания объектов базового класса, просто сделай дефолтный конструктор защищенным. Хотя для абстрактных классов это излишняя мера, поскольку компилятор и так не позволит создать экземпляр абстрактного класса.