문제

I am new to c++. When I try to compile the code below , I get this error

constructor for 'child' must explicitly initialize the base class 'parent' which does not have a default constructor child::child(int a) {

here is my class

#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[]) 
{

}

Why I am getting this error ? How can I resolve it ? Thanks in advance

도움이 되었습니까?

해결책

The parent class has an explicit constructor, so compiler will not add an implicit 'empty' constructor to it. Additionally your constructor has a parameter, so compiler can not generate an implicit call to it. That's why you must do it explicitly.

This way:

 child::child(int a) : parent(a)
 {
 }

다른 팁

When you initialize an object of a derived class, the base class part has to be constructed first. If you don't initialize it yourself in the derived class' constructor by calling one of its constructors, the compiler will attempt use the default constructor of the base class. In your case the default constructor is not defined because you already provided a custom constructor.

To solve this you will either have to provide a default constructor for the base class or simply call its constructor in the derived class' constructor's initializer list:

child::child(int a) : parent(a)
 {
 }

At the risk of repeating the error message you got: a child class constructor must invoke its parent's constructor.

The compiler will add an automatic invocation of the parent's default (argumentless) constructor. If the parent does not have a default constructor, you must explicitly invoke one of the constructors it does have by yourself.

The compiler has to enforce this to ensure that the functionality that the child class has inherited from the parent is set up correctly... for example, initialising any private variables that the child has inherited from the parent, but cannot access directly. Even though your class doesn't have this problem, you must still follow the rules.

Here are some examples of constructors in classes using inheritance:

This is fine, ParentA has a default constructor:

class ParentA
{
};

class ChildA
{
public:
    ChildA() {}
};

This is not fine; ParentB has no default constructor, so ChildB1 class must explicitly call one of the constructors itself:

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) {}
};

This is fine, we're calling ParentB's constructor explicitly:

class ChildB2 : public ParentB
{
    float m_b;

public:
    ChildB2(int a, float b) : ParentB(a), m_b(b) {}
};

This is fine, ParentC has a default constructor that will be called automatically:

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) {}
};

Another example where a MyBook class is being derived from the base class Book. Now a custom constructor with two arguments are supplied for the base class constructor, therefore there is no default constructor for the base class. When inside the main function, a derived class object novel is created, at first the compiler will attempt to invoke the base class constructor which does not exist. So, the base class constructor needs to be explicitly called from the derived class constructor to initialize any private variables that the derived class has inherited from the base class but can not access directly (e.g. title string variable). As user rook mentioned, we need follow these rules. You can get more detailed information from the nice explanation of Initialization Lists by Alex Allain. So, Initialization Lists are must required when there is no defined dafault constructor and also for initializing constant members. He summarises-

Before the body of the constructor is run, all of the constructors for its parent class and then for its fields are invoked. By default, the no-argument constructors are invoked. Initialization lists allow you to choose which constructor is called and what arguments that constructor receives.

#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;
}

Hi Just try add default constructor in your parent class (No argument constructor) then compile it. Hope this might resolve your problem.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top