C++ 从派生类构造函数调用基类构造函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10282787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:51:53  来源:igfitidea点击:

Calling the base class constructor from the derived class constructor

c++inheritanceconstructorvisibilityderived-class

提问by Joy

I have a question:

我有个问题:

Say I have originally these classes which I can't change (let's say because they're taken from a library which I'm using):

假设我最初有这些我无法更改的类(假设它们是从我正在使用的库中获取的):

class Animal_
{
public:
    Animal_();
    int getIdA()
    {
        return idA;
    };
    string getNameA()
    {
        return nameA;
    }
private:
    string nameA;
    int idA;
}

class Farm
{
public :
    Farm()
    {
        sizeF=0;
    }
    Animal_* getAnimal_(int i)
    {
        return animals_[i];
    }
    void addAnimal_(Animal_* newAnimal)
    {
        animals_[sizeF]=newAnimal;
        sizeF++;
    }

private:
    int sizeF;
    Animal_* animals_[max];
}

But then I needed a class where I just add couple of fields so I did this:

但是后来我需要一个只添加几个字段的类,所以我这样做了:

class PetStore : public Farm
{
public :
    PetStore()
    {
     idF=0;
    };
private:
    int idF;
    string nameF;
}

But I can't initialize my derived class, I mean I did this Inheritance so I can add animals to my PetStore but now since sizeF is private how can I do that? I'm thinking maybe in the PetStore default constructor I can call Farm()... so any idea?

但是我无法初始化我的派生类,我的意思是我做了这个继承,所以我可以将动物添加到我的 PetStore 但现在因为 sizeF 是私有的,我该怎么做?我在想也许在 PetStore 默认构造函数中我可以调用 Farm() ......所以有什么想法吗?

回答by James Kanze

The constructor of PetStorewill call a constructor of Farm; there's no way you can prevent it. If you do nothing (as you've done), it will call the default constructor (Farm()); if you need to pass arguments, you'll have to specify the base class in the initializer list:

的构造函数PetStore将调用 的构造函数Farm;你没有办法阻止它。如果您什么都不做(就像您所做的那样),它将调用默认构造函数 ( Farm());如果需要传递参数,则必须在初始化列表中指定基类:

PetStore::PetStore()
    : Farm( neededArgument )
    , idF( 0 )
{
}

(Similarly, the constructor of PetStorewill call the constructor of nameF. The constructor of a class alwayscalls the constructors of all of its base classes and all of its members.)

(类似地, 的构造函数PetStore将调用 的构造函数 nameF。类的构造函数总是调用其所有基类及其所有成员的构造函数。)

回答by Luchian Grigore

First off, a PetStoreis not a farm.

首先,aPetStore不是农场。

Let's get past this though. You actually don't need access to the private members, you have everything you need in the public interface:

让我们过去吧。您实际上不需要访问私有成员,您可以在公共接口中获得所需的一切:

Animal_* getAnimal_(int i);
void addAnimal_(Animal_* newAnimal);

These are the methods you're given access to and these are the ones you should use.

这些是您有权访问的方法,这些是您应该使用的方法。

I mean I did this Inheritance so I can add animals to my PetStore but now since sizeF is private how can I do that ??

我的意思是我做了这个继承,所以我可以将动物添加到我的 PetStore 但现在因为 sizeF 是私有的,我该怎么做?

Simple, you call addAnimal. It's publicand it also increments sizeF.

很简单,你打电话addAnimal。它是public并且它也会增加sizeF

Also, note that

另外,请注意

PetStore()
{
 idF=0;
};

is equivalent to

相当于

PetStore() : Farm()
{
 idF=0;
};

i.e. the base constructor is called, base members are initialized.

即调用基构造函数,初始化基成员。

回答by Michael Wild

The base-class constructor is already automatically called by your derived-class constructor. In C++, if the base class has a default constructor (takes no arguments, can be auto-generated by the compiler!), and the derived-class constructor does not invoke another base-class constructor in its initialisation list, the default constructor will be called. I.e. your code is equivalent to:

派生类构造函数已经自动调用了基类构造函数。在 C++ 中,如果基类有一个默认构造函数(不带参数,可以由编译器自动生成!),并且派生类构造函数没有在其初始化列表中调用另一个基类构造函数,则默认构造函数将叫做。即你的代码相当于:

class PetStore: public Farm
{
public :
    PetStore()
    : Farm()     // <---- Call base-class constructor in initialision list
    {
     idF=0;
    };
private:
    int idF;
    string nameF;
}

回答by Klaim

but I can't initialize my derived class, I mean I did this Inheritance so I can add animals to my PetStore but now since sizeF is private how can I do that ?? so I'm thinking maybe in the PetStore default constructor I can call Farm()... so any Idea ???

但我无法初始化我的派生类,我的意思是我做了这个继承,所以我可以将动物添加到我的 PetStore 但现在因为 sizeF 是私有的,我该怎么做?所以我在想也许在 PetStore 默认构造函数中我可以调用 Farm() ......所以有什么想法吗???

Don't panic.

不要惊慌。

Farm constructor will be called in the constructor of PetStore, automatically.

农场构造函数将在的PetStore的构造函数被调用,自动

See the base class inheritance calling rules: What are the rules for calling the superclass constructor?

参见基类继承调用规则:调用超类构造函数的规则是什么?

回答by Isabella Engineer

Calling Base constructor in the Derived Constructor

在派生构造函数中调用基构造函数

Note:If we don't use super() keyword then it will call default constructor of Base Classwhich in this case is illegal as hereBase ClassConstructor takes three arguments.
So,it becomes neccessary to use super( )keyword with desired arguments.
Remember:
1).From Outside the class,a constructor is alwayscalled with new operator.
2). From inside the class,it may be called through this( ) keywordOR super( ) keyword.
3).this( ) keyword can be used to call another Constructor of the same class(See Inner Class Concept).
4).Unlike other methods( i.e functions() ),Constructors are not inherited.
5).If you name Method Name Of Base Class Same as of Derived Class Method Name then base classwill notbe called.
6).Whenever you create object of Derived Classthen constructorof Base Classruns first(See program below).

注意:如果我们不使用 super() 关键字,那么它将调用基类的默认构造函数,在这种情况下这是非法的,因为这里的基类构造函数接受三个参数。
因此,有必要使用带有所需参数的super()关键字。
请记住:
1).从类外部,总是使用 new 运算符调用构造函数。
2)。从类内部,它可以通过this( ) 关键字super( ) 关键字调用。
3)。this() 关键字可用于调用同一类的另一个构造函数(参见内部类概念)
4).不像其他方法(即functions()),构造函数不是继承的
5)。如果你命名方法名基类一样的派生类的方法名称基类不会被调用。
6)。每当创建的对象派生类然后构造基类首先运行(下面参见方案)。

class demo
{
    public static void main(String args[])
    {   
        derived1 d1=new derived1("Tom","Dad",21,"Programming","Cooking");
        derived2  d2=new derived2("Tom","Dad",21,500);

    d1.baseDisplay();//Calling Base class's baseDisplay() via derived class object
        d1.display();

    d2.baseDisplay();//Calling Base class's baseDisplay() via derived class object
        d2.display();
    }
}

class base
{
    private
    String name;
    String fatherName;
    int age;
    String interest;
    String hobby;
    int piggyBankAmount;
    base(String name,String fatherName,int age)
    {
        this.name=name;
        this.fatherName=fatherName;
        this.age=age;
    }

    public void baseDisplay()
    {
        System.out.println("Name:"+name+"\nFather's Name:"+fatherName+"\nAge:"+age);
    }

}


class derived1 extends base
{   /* String interest;         Note we inherited these data members from Base Class
        String hobby;   */
    derived1(String name,String fatherName,int age,String interest,String hobby)
    {
        super(name,fatherName,age);
        this.interest=interest;
        this.hobby=hobby;
    }

    public void display()
    {
        System.out.println("Hobby:"+hobby+"\nInterest:"+interest);

    }


}

class derived2 extends base
{         //int piggyBankAmount;  Note we inherited this data member from Base Class
    derived2(String name,String fatherName,int age,int piggyBankAmount)
    {
        super(name,fatherName,age);
        this.piggyBankAmount=piggyBankAmount;

    }

    public void display()
    {
        System.out.println("piggyBankAmount:"+piggyBankAmount);
    }


}

Output:

输出:

  Name:Tom
  Father's Name:Dad
  Age:21
  Hobby:Cooking
  Interest:Programming
  Name:Tom
  Father's Name:Dad
  Age:21
  piggyBankAmount:500

Program to show Constructor of Base Class Runs First When Derived Class Object is created

创建派生类对象时显示基类构造函数首先运行的程序

    class demo
    {
        public static void main(String args[])
        {   
            derived1 d1=new derived1("Tom","Dad",21,"Programming","Cooking");
            derived2  d2=new derived2("Tom","Dad",21,500);

            d1.display();
            d2.display();
        }
    }

    class base
    {
        private
        String name;
        String fatherName;
        int age;
        String interest;
        String hobby;
        int piggyBankAmount;
        base(String name,String fatherName,int age)
        {
            this.name=name;
            this.fatherName=fatherName;
            this.age=age;

            System.out.println("Name:"+name+"\nFather's Name:"+fatherName+"\nAge:"+age);//See Constructor of Base class runs first
        }



    }


    class derived1 extends base
    {   /* String interest;         Note we inherited these data members from Base Class
            String hobby;   */
        derived1(String name,String fatherName,int age,String interest,String hobby)
        {
            super(name,fatherName,age);
            this.interest=interest;
            this.hobby=hobby;
        }

        public void display()
        {
            System.out.println("Hobby:"+hobby+"\nInterest:"+interest);

        }


    }

    class derived2 extends base
    {         //int piggyBankAmount;  Note we inherited this data member from Base Class
        derived2(String name,String fatherName,int age,int piggyBankAmount)
        {
            super(name,fatherName,age);
            this.piggyBankAmount=piggyBankAmount;

        }

        public void display()
        {
            System.out.println("piggyBankAmount:"+piggyBankAmount);
        }


    }

Output:

输出:

    Name:Tom
    Father's Name:Dad
    Age:21
    Name:Tom
    Father's Name:Dad
    Age:21
    Hobby:Cooking
    Interest:Programming
    piggyBankAmount:500