从派生类构造函数中调用基类构造函数

时间:2012-04-23 14:45:07

标签: c++ inheritance constructor visibility derived-class

我有一个问题:

说我原来这些我无法改变的课程(让我们说它们来自我正在使用的图书馆):

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

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

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

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

5 个答案:

答案 0 :(得分:57)

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

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

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

答案 1 :(得分:12)

首先,PetStore不是农场。

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

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

这些是您可以访问的方法,这些是您应该使用的方法。

  

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

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

另外,请注意

PetStore()
{
 idF=0;
};

相当于

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

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

答案 2 :(得分:5)

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

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

答案 3 :(得分:2)

  

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

不要惊慌。

将在PetStore的构造函数中调用Farm构造函数,自动

请参阅基类继承调用规则:What are the rules for calling the superclass constructor?

答案 4 :(得分:-3)

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

注意:如果我们不使用super()关键字,那么它将调用 Base Class 的默认构造函数,在本例中是非法这里 基类构造函数有三个参数 因此,必须使用带有所需参数的 super()关键字 记住:
1)。从课外开始,构造函数 总是 用new运算符调用。
2)。从课堂内部开始,可以通过 this()关键字 super()关键字进行调用。
3)。 this()关键字可用于调用相同类 的另一个构造函数(参见内部类概念)
4)。与其他方法(即函数())不同,构造函数不被继承
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);
    }


}

输出:

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

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

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


    }

输出:

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