Удаленный деструктор в классе появился как виртуальный/прямой базовый класс или как тип нестатического элемента данных

Существует правило о случаях, когда конструктор copy/move неявно удален:

Неявно объявленный конструктор копирования/перемещения является встроенным общедоступным член его класса. Конструктор копирования/перемещения по умолчанию для класса X определяется как удаленный (8.4.3), если X имеет:

[...]

- любой прямой или виртуальный базовый класс или нестатический член данных типа с деструктором, который удален или недоступен по умолчанию конструктор или

[...]

Потому что я не могу найти пример, отражающий правило, мне это не ясно. Рассмотрим следующий код:

struct A
{
    ~A() = delete;
};

struct B : A
{
    A a;
    B(){ }; //error error: attempt to use a deleted function B(){ };
    B(const B&&)  = delete;
};

B *b = new B;

int main() { }

DEMO

Из-за удаленного перемещения конструктор не принимает участия в разрешении перегрузки, я ожидал, что ошибка будет чем-то вроде "Конструктор копирования неявно удален". Но вместо этого я получил ошибку об удаленном B(), который я определил явно. Не могли бы вы привести пример, отражающий это правило?

Ответы

Ответ 1

Основываясь только на выдержке, которую вы предоставили, приведен пример:

struct inner
{
    ~inner() = delete;
};

struct outer
{
    inner inst;

    // Can't destroy "inst"; outer now has an implicitly
    // deleted destructor and copy/move constructor.
};

Ответ 2

Посмотрите на пятую точку: ясно сказано, что вы удалили базовый класс dtor, чтобы у вас возникла эта проблема.

ссылка: http://en.cppreference.com/w/cpp/language/default_constructor

Удаленный неявно объявленный конструктор по умолчанию

Неявно объявленный или дефолтный конструктор по умолчанию для класса T имеет значение undefined (до С++ 11), определенный как удаленный (начиная с С++ 11), если выполняется одно из следующих условий:

  • T имеет член ссылочного типа без скобки или равного инициализатор. (поскольку С++ 11)

  • T имеет член const без пользовательского конструктора по умолчанию или (например, С++ 11).

  • T имеет член (без инициализатора с фигурной скобкой) (поскольку С++ 11), который имеет удаленный конструктор по умолчанию или его конструктор по умолчанию является двусмысленным или недоступным из этого конструктора.

  • T имеет прямую или виртуальную базу, которая имеет удаленные значения по умолчанию конструктор, или он неоднозначен или недоступен из этого конструктор.

  • T имеет прямую или виртуальную базу, которая имеет удаленный деструктор, или деструктор, который недоступен для этого конструктора.

  • T - объединение, по крайней мере, с одним вариантом с нетривиальным конструктор по умолчанию.     (поскольку С++ 11)

  • T является объединением, и все его варианты являются const.