Вызов конструктора базового класса из конструктора производного класса

у меня вопрос:

скажем, у меня изначально есть эти классы, которые я не могу изменить (скажем, потому что они взяты из библиотеки, которую я использую):

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

но я не могу инициализировать свой производный класс, я имею в виду, что я сделал это наследование, чтобы я мог добавлять животных в свой зоомагазин, но теперь, поскольку sizeF является частным, как я могу это сделать? Я думаю, может в PetStore конструктор по умолчанию я могу вызвать Farm ()... поэтому любая идея?

5 ответов


конструктор PetStore вызовет конструктор Farm; там вы не сможете предотвратить это. Если вы ничего не сделаете (как вы сделали), это будет вызовите конструктор по умолчанию (Farm()); Если вам нужно передать аргументы, вам нужно будет указать базовый класс в списке инициализаторов:

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

(аналогично, конструктор PetStore вызовет конструктор nameF. Конструктор класса всегда вызывает конструкторы все его базовые классы и все его члены.)


во-первых, a PetStore - это не ферма.

давайте пройдем через это. На самом деле вам не нужен доступ к частным членам, у вас есть все, что вам нужно в публичном интерфейсе:

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

это методы, к которым вы получаете доступ, и это те, которые вы должны использовать.

Я имею в виду, что я сделал это наследство, чтобы я мог добавить животных в свой зоомагазин, но теперь, поскольку sizeF является частным, как я могу это сделать ??

простой, вы звоните addAnimal. Это public и он также увеличивает sizeF.

внимание:

PetStore()
{
 idF=0;
};

эквивалентно

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

т. е. вызывается базовый конструктор, инициализируются базовые элементы.


конструктор базового класса уже автоматически вызывается конструктором производного класса. В C++, если базовый класс имеет конструктор по умолчанию (без аргументов, может быть автоматически сгенерирован компилятором!), и конструктор производного класса не вызывает другой конструктор базового класса в списке инициализации, будет вызван конструктор по умолчанию. Т. е. ваш код эквивалентен:

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

но я не могу инициализировать свой производный класс, я имею в виду, что я сделал это наследование поэтому я могу добавить животных в свой зоомагазин, но теперь, поскольку sizeF является частным, как могу я это сделать ?? так что я думаю, может быть, в зоомагазине дефолт конструктор я могу вызвать Farm ()... поэтому любая идея ???

Не паникуйте.

конструктор фермы будет вызываться в конструкторе PetStore,автоматически.

см. правила вызова наследования базового класса: каковы правила вызова конструктора суперкласса?


вызов базового конструктора в производном конструкторе

Примечание:если мы не используем ключевое слово super (), он вызовет конструктор по умолчанию Базовый Класс, который в данном случае является незаконным, так как здесь Базовый Класс конструктор принимает три аргумента.
Таким образом, становится необходимым использовать super () ключевое слово с заданными аргументами.
помните:
1).извне класс,конструктор всегда названием с новым оператором.
2). Изнутри класса он может быть вызван через этот( ) ключевое слово или ключевое слово super ().
3).этот( ) ключевое слово можно использовать для вызова другого конструктора тот же класс(См. Концепцию Внутреннего Класса).
4).В отличие от других методов (i.e функции ()), конструкторы не унаследовал.
5).Если вы назовете Имя Метода Базового Класса как Имя Метода Производного Класса затем базовый класс будет не называться.
6).Всякий раз, когда вы создаете объект Производный Класс затем конструктор of Базовый Класс запускается первым (см. программу ниже).

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