Błąd: konstruktor klasy bazowej musi jawnie zainicjować konstruktor klasy nadrzędnej


Jestem nowy w C ++. Kiedy próbuję skompilować poniższy kod, pojawia się ten błąd
constructor for 'child' must explicitly initialize the
base class 'parent' which does not have a default constructor
child::child(int a) {
oto moja klasa
<pre class="lang-cpp prettyprint-override">
#include<iostream>
using namespace std;class Parent
{
public :
int x;
Parent(int a);
int getX();
};
Parent::Parent(int a)
{
x = a;
}
int Parent::getX()
{
return x;
}
class Child : public Parent
{
public:
Child(int a);
};
Child::Child(int a)
{
x = a;
}
int main(int n , char *argv[])
{}

Dlaczego otrzymuję ten błąd?
Jak mogę rozwiązać ten problem?
Z góry dziękuję
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Klasa nadrzędna ma jawny konstruktor, więc kompilator nie doda do niej niejawnego „pustego” konstruktora. Ponadto Twój konstruktor ma parametr, więc kompilator nie może wygenerować niejawnego wywołania go. Dlatego musisz to zrobić wyraźnie.
A zatem:
child::child(int a) : parent(a)
{
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Podczas inicjowania obiektu klasy pochodnej najpierw należy zbudować część klasy bazowej. Jeśli nie zainicjujesz go samodzielnie w konstruktorze klasy pochodnej przez wywołanie jednego z jej konstruktorów, kompilator spróbuje użyć domyślnego konstruktora klasy bazowej. W Twoim przypadku żaden domyślny konstruktor nie jest zdefiniowany, ponieważ podałeś już konstruktora niestandardowego.
Aby rozwiązać ten problem, będziesz musiał albo podać domyślny konstruktor dla klasy bazowej, albo po prostu wywołać jego konstruktor na liście inicjalizacyjnej konstruktora klasy pochodnej:
child::child(int a) : parent(a)
{
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Ryzykując powtórzenie otrzymanego komunikatu o błędzie: konstruktor klasy potomnej musi wywołać konstruktor swojej klasy nadrzędnej.
Kompilator doda automatyczne wywołanie do domyślnego konstruktora nadrzędnego (bez argumentów). Jeśli rodzic nie ma domyślnego konstruktora, musisz jawnie wywołać jeden z konstruktorów, który sam wykonuje.
Kompilator musi to zastosować, aby upewnić się, że funkcjonalność odziedziczona przez klasę podrzędną po klasie nadrzędnej jest poprawnie skonfigurowana ... na przykład inicjalizacja wszelkich zmiennych prywatnych, które dziecko odziedziczyło po rodzicu, ale nie można uzyskać do nich bezpośredniego dostępu. Nawet jeśli Twoja klasa nie ma tego problemu, nadal powinieneś przestrzegać zasad.
Oto kilka przykładów konstruktorów w klasach, które używają dziedziczenia:
To jest w porządku, ParentA ma domyślnego konstruktora:
class ParentA
{
};class ChildA
{
public:
ChildA() {}
};

To nie jest normalne; ParentB nie ma domyślnego konstruktora, więc klasa ChildB1 musi jawnie wywołać jeden z samych konstruktorów:
class ParentB
{
int m_a;public:
ParentB(int a) : m_a(a) {}
};class ChildB1 : public ParentB
{
float m_b;public:
// You'll get an error like this here:
// "error: no matching function for call to ‘ParentB::ParentB()’"
ChildB1 (float b) : m_b(b) {}
};

To jest w porządku, jawnie nazywamy konstruktora ParentB:
class ChildB2 : public ParentB
{
float m_b;public:
ChildB2(int a, float b) : ParentB(a), m_b(b) {}
};

W porządku, ParentC ma domyślnego konstruktora, który zostanie wywołany automatycznie:
class ParentC
{
int m_a;public:
ParentC() : m_a(0) {}
ParentC(int a) : m_a(a) {}
};class ChildC: public ParentC
{
float m_b;public:
ChildC(float b) : m_b(b) {}
};
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Inny przykład, w którym klasa MyBook pochodzi z książki klas bazowych. Dla konstruktora klasy bazowej jest teraz dostarczany niestandardowy konstruktor z dwoma argumentami, więc nie ma domyślnego konstruktora dla klasy bazowej. Kiedy nowy obiekt klasy pochodnej jest tworzony wewnątrz funkcji main, kompilator najpierw spróbuje wywołać konstruktor klasy bazowej, która nie istnieje. W związku z tym konstruktor klasy bazowej musi być jawnie wywoływany z konstruktora klasy pochodnej, aby zainicjować wszelkie zmienne prywatne, które klasa pochodna dziedziczy z klasy bazowej, ale nie można uzyskać do nich bezpośredniego dostępu (na przykład zmiennej w postaci ciągu nagłówka). Jak już wspomniał użytkownik

ręce
https://stackoverflow.com/users/1450890/rook, musimy przestrzegać tych zasad. Więcej szczegółów można uzyskać z dobrego wyjaśnienia

listy inicjalizacyjne
http://www.cprogramming.com/tu ... Alexa Alleina
https://plus.google.com/113987 ... or... Dlatego listy inicjalizacyjne powinny być wymagane, gdy nie ma określonego konstruktora dafault, a także do inicjowania stałych składowych. Podsumowuje-

Przed uruchomieniem treści konstruktora wszystkie konstruktory dla
klasę nadrzędną, a następnie jej pola. Domyślna
wywoływane są konstruktory bez argumentów. Listy inicjalizacyjne pozwalają
wybierz, który konstruktor jest wywoływany i jakie argumenty
pobiera tego konstruktora.

#include <iostream>
#include <cstdio>using namespace std;class Book {
private:
string title;
protected:
string author;
public:
Book(string t, string a) {
title = t;
author = a;
};
virtual void display() = 0;
};class MyBook : public Book {
private:
const string className;
protected:
int price;
public:
// Book(t,a) needs to be called before the {} block to initialize, otherwise error (does not match to Book::Book() default constructor will occur)
MyBook(string t, string a, int p) : Book(t, a), className("MyClass"), price(p){
}; void display() {
cout << "Title: " << getTitle() << endl;
cout << "Author: " << author << endl;
cout << "Price: " << price << endl;
};
};int main() {
string title, author;
int price;
getline(cin, title);
getline(cin, author);
cin >> price;
MyBook novel(title, author, price);
novel.display(); return 0;
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Cześć, po prostu spróbuj dodać domyślny konstruktor do klasy nadrzędnej (bez konstruktora argumentów), a następnie skompiluj go. Mam nadzieję, że to rozwiąże Twój problem.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się