Проблема с вызовом конструктора из вложенного абстрактного родительского класса - PullRequest
1 голос
/ 21 апреля 2020

У меня есть следующий фрагмент кода, и я ожидаю, что будет вызван конструктор из родительского класса First::Inner.

class First {
    public:
        class Inner {
            public:
                Inner(int x) {}
                virtual ~Inner() = default;
        };
        virtual Inner* begin() = 0;
};

class Second: public First {
    public:
        class Inner: public First::Inner {
        };
        Inner* begin() {
            return new Inner(1);
        }
};

int main()
{
    Second s;

    return 0;
}

Вместо этого я получил ошибку компиляции в компиляторе:

main.cpp: In member function ‘virtual Second::Inner* Second::begin()’:
main.cpp:16:31: error: no matching function for call to ‘Second::Inner::Inner(int)’

Работает, если весь конструктор Inner(int x) {} перемещен из базового класса First::Inner в производный Second::Inner. Но я бы хотел оставить конструктор в базовом классе.

Что не так с кодом и как я могу исправить ошибку?

1 Ответ

4 голосов
/ 21 апреля 2020

Проблема в том, что класс Second::Inner не имеет конструктора, принимающего int, тогда new Inner(1); завершится неудачей.

Вы можете наследовать конструктор как

class Inner: public First::Inner {
    using First::Inner::Inner;
};

LIVE

Если объявление использования ссылается на конструктор прямой базы определяемого класса (например, using Base::Base;), все конструкторы эта база (игнорируя доступ к элементу) становится видимой для разрешения перегрузки при инициализации производного класса.

Если разрешение перегрузки выбирает один из унаследованных конструкторов при инициализации объекта такого производного класса, то подобъект Base, из которого наследованный конструктор инициализируется с помощью унаследованного конструктора, а все остальные базы и члены Derived инициализируются так, как если бы использовался конструктор по умолчанию (при его использовании используются инициализаторы членов по умолчанию, в противном случае происходит инициализация по умолчанию). Вся инициализация обрабатывается как один вызов функции: инициализация параметров унаследованного конструктора выполняется последовательно до инициализации любой базы или члена производного объекта.

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