Я пытаюсь понять использование частных конструкторов с наследованием (я новичок в C ++), и при тестировании обнаружилось следующее:

vestigial.cc: In constructor ‘ExtraSample::ExtraSample()’:
vestigial.cc:34:16: error: no matching function for call to ‘Sample::Sample()’
  ExtraSample() {};

Используя это для компиляции: g ++ -std = c ++ 11 vestigial.cc

Вот код:

#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace std;

class Sample {
public:
    ~Sample(){
        cout << name << " died " << endl;
    };
    void what() {
        cout << name << " hat" << endl;
    }
private:
    Sample(const string n) {
        name = n;
    };
    friend class SampleOwner;
    string name;
};


class SampleOwner {
public:
    static Sample* createSample(const string n) {
        return new Sample(n);
    }
};

class ExtraSample : Sample {
public:
private:
    ExtraSample() {};
};

В итоге - почему этот код недействителен?

Спасибо!

0
Catalyst 6 Мар 2014 в 06:26

2 ответа

Лучший ответ

Когда инициализируется производный класс, сначала необходимо инициализировать базовый класс. Вы можете указать, какой конструктор базового класса вызывать, указав имя базового класса в инициализаторе ctor в конструкторе производного класса. Если вы не укажете это явно, компилятор попытается вызвать конструктор базового класса по умолчанию.

Однако у этого базового класса нет конструктора по умолчанию, отсюда и сообщение об ошибке. Обратите внимание, что вы все равно не сможете вызвать Sample::Sample(string), так как он частный, поэтому фактически его невозможно получить от Sample.

Если вы хотите, чтобы конструктор базового класса мог вызывать только производный класс, вместо этого сделайте его protected!

7
Brian Bi 6 Мар 2014 в 02:37

Почему код недействителен?

Вызывающий не может получить доступ к частному конструктору.


Есть несколько способов сделать возможным вызов частного конструктора базового класса.

  • изменить базовый класс, чтобы называть производный класс своим другом

  • добавить именованный конструктор к базовому классу как защищенный или общедоступный, и он может вызывать производный конструктор. (именованные методы идиомы конструктора статичны)

  • измените базовый класс, чтобы назвать функцию другом.

  • изменить частный конструктор, чтобы он был защищен

2
2785528 6 Мар 2014 в 04:34