Инициализация абстрактного класса с конструктором удаленных копий - PullRequest
0 голосов
/ 11 февраля 2019

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

struct connection {
    // Make object non copyable.
    connection(const connection &) = delete;
    auto operator=(const connection &) -> connection & = delete;
    // Make class abstract.
    virtual ~connection() = 0;
  };

Я пытаюсь создать класс, который наследуется от него:

struct abstract_connection : connection {...};

но я получаю следующую ошибку в конструкторе:

constructor for 'abstract_connection' must explicitly initialize the base class 'connection' which does not have a default constructor

Почему это происходит при удалении конструктора и оператора копирования?

Ответы [ 3 ]

0 голосов
/ 11 февраля 2019

Вы определили конструктор копирования как себя (= delete).Таким образом, Compiler увидел это, и он не генерирует конструктор по умолчанию.Поэтому в этом случае при определении нового класса abstract_connection, унаследованного от соединения базового класса, компилятор не знает, как создать конструктор для нового производного класса abstract_connection.Так что сообщили об этой ошибке.

0 голосов
/ 11 февраля 2019

Правила автоматической генерации специальных функций-членов в Effective Modern C ++ четко объяснены Скоттом Мейерсом, пункт 17, стр.109.

В двух словах, когда вы переопределяете / переопределяете конструктор, тогдавам нужно определить все необходимые конструкторы.Поскольку вы удалили конструктор копирования, вам необходимо определить конструктор по умолчанию для базового класса.Это происходит потому, что вы используете конструктор по умолчанию при определении производного класса.

Этот код struct abstract_connection : connection {...}; (без какой-либо информации) означает, что вы, скорее всего, инициализируете abstract_connection, используя ctor по умолчанию изconnection.Но ctor по умолчанию из connection не определен.

Более того, вам нужно определить свой dtor, даже если он считается виртуальной функцией.Код ниже компилируется и запускается здесь .

struct connection
{
    connection() = default;
    connection(const connection &) = delete;

    auto operator=(const connection &) -> connection & = delete;

    virtual ~connection() = 0;
};

connection::~connection()
{}

struct abstract_connection : connection
{
    abstract_connection() : connection()
    {}

    ~abstract_connection() = default;
};

int main()
{
    abstract_connection foo;
}
0 голосов
/ 11 февраля 2019

Согласно стандарту:

[class.default.ctor # 1]

[...] Если пользователь не объявленконструктор для класса X, неявный конструктор без параметров неявно объявляется как дефолтный ( [dcl.fct.def] ).[..]

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

struct connection {

    connection(const connection &) = delete;
    auto operator=(const connection &) -> connection & = delete;
    virtual ~connection() = 0;

protected: // You likely want to make it protected.
    connection() = default;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...