37

質問があります:

私が変更できないこれらのクラスをもともと持っているとしましょう(私が使用しているライブラリから取得したためとしましょう):

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

ただし、派生クラスを初期化できません。animalsつまり、この継承を行ったので追加できますが、プライベートなのでどうすればそれを行うことができますかPetStore? sizeF私はおそらくPetStoreデフォルトのコンストラクターで呼び出すことができると考えていFarm()ます...だから何か考えはありますか?

4

4 に答える 4

80

のコンストラクターは、のPetStoreコンストラクターを呼び出しFarmます。それを防ぐ方法はありません。(行ったように) 何もしない場合は、既定のコンストラクター ( Farm()) が呼び出されます。引数を渡す必要がある場合は、初期化リストで基本クラスを指定する必要があります。

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

(同様に、 のコンストラクターは のコンストラクターPetStoreを呼び出します nameF。クラスのコンストラクターは常に、そのすべての基底クラスとそのすべてのメンバーのコンストラクターを呼び出します。)

于 2012-04-23T14:51:15.077 に答える
15

まず、aPetStoreは農場ではありません。

しかし、これを乗り越えましょう。実際には、プライベート メンバーにアクセスする必要はありません。必要なものはすべてパブリック インターフェイスにあります。

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

これらは、アクセスが許可されているメソッドであり、使用する必要があるメソッドです。

つまり、この継承を行ったので、ペットストアに動物を追加できますが、sizeF はプライベートなので、どうすればそれを行うことができますか??

簡単に、あなたは を呼び出しますaddAnimal。それpublicはまた増加しますsizeF

また、

PetStore()
{
 idF=0;
};

と同等です

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

つまり、基本コンストラクターが呼び出され、基本メンバーが初期化されます。

于 2012-04-23T14:48:18.000 に答える
6

基本クラスのコンストラクターは、派生クラスのコンストラクターによって既に自動的に呼び出されています。C++ では、基本クラスにデフォルト コンストラクターがあり (引数を取らず、コンパイラーによって自動生成できます!)、派生クラス コンストラクターがその初期化リストで別の基本クラス コンストラクターを呼び出さない場合、デフォルト コンストラクターは呼ばれます。つまり、あなたのコードは以下と同等です:

class PetStore: public Farm
{
public :
    PetStore()
    : Farm()     // <---- Call base-class constructor in initialision list
    {
     idF=0;
    };
private:
    int idF;
    string nameF;
}
于 2012-04-23T14:50:36.933 に答える
2

しかし、派生クラスを初期化できません。つまり、この継承を行ったので、PetStore に動物を追加できますが、sizeF はプライベートなので、どうすればそれを行うことができますか?? だから私はおそらくPetStoreのデフォルトコンストラクターでFarm()を呼び出すことができると考えています...だからどんなアイデア???

パニックにならない。

Farm コンストラクターは、PetStore のコンストラクターで自動的に呼び出されます。

基本クラスの継承呼び出し規則を参照してください:スーパークラス コンストラクターを呼び出すための規則は何ですか?

于 2012-04-23T14:48:49.470 に答える