Унаследуйте конструкторы с помощью, но сделайте их вне строки - PullRequest
0 голосов
/ 24 января 2019

Рассмотрим следующий короткий, но многофайловый пример :

// ************************** unit.h **************************
#pragma once

#include <memory>

struct S;

struct B {
    B(int) {};
    virtual ~B() {};
};

struct D : B {
   D(int);
   ~D() override;
   std::unique_ptr<S> p;
};

// ************************** unit.cpp **************************
#include "unit.h"

struct S {};

D::D(int i) : B(i) {}

D::~D() = default; 

// ************************** prog.cc **************************
#include "unit.h"

int main()
{
    D d(42);
}

Существует два класса с наследованием: базовый B и производный D. Класс D содержит определение члена unique_ptr только с объявленным классом S. Чтобы эта схема работала, мне нужно определить как конструктор, так и деструктор класса D вне строки (т. Е. Реализовано в unit.cpp , где полное определение S видно).

Вопрос: возможно ли использовать объявление using B::B; в классе D, чтобы наследовать конструкторы B, чтобы предотвратить ручную запись D::D(int i) : B(i) {}, но сделать это наследование вне строки, чтобы предотвратить ошибка компиляции ?

error: invalid application of 'sizeof' to an incomplete type 'S'

1 Ответ

0 голосов
/ 24 января 2019

можно ли использовать объявление B::B; в классе D, чтобы наследовать конструкторы B для предотвращения записи вручную D::D(int i) : B(i) {}

Это возможно.

Наряду с предварительным объявлением struct S также объявить его удалитель:

struct S;

struct SDeleter { void operator()(S*) const; }; // Defined elsewhere.

А потом:

struct D : B {
   using B::B;
   std::unique_ptr<S, SDeleter> p;
};

Определение void SDeleter::operator()(S*) const должно быть предоставлено в другой единице перевода (.cc), которая имеет доступ к определению S.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...