2017-04-14 15 views
1

私はフラワーとサブクラスローズ、リリー、ジャスミンと呼ばれるスーパークラスを持っているプログラムを持っています。C++のmain関数からクラスのプライベートコンストラクタにアクセスするにはどうすればよいですか?

花の特徴を記述する2つの変数と、ゲッター関数を持つパブリックメンバーと、サブクラス花の色を印刷する純仮想関数(string getColor()と呼ばれる)を持つメンバーです。また、各花の特性を出力するパブリックメンバー関数も用意されています(void printFlower(string name))。

私はRose、Lily、Jasmineのクラスを実装しようとしています。クラス内のpublicアクセス修飾子を使用せずにクラスを実装する必要があります。したがって、クラス内のすべてが保護されているか、プライベートである(コンストラクタさえも)必要があります。私はローズ、リリー、ジャスミンが親クラスのFlowerから公に継承していることを知っています。私の主な機能には

は、私はこれを持っている:

int main(){ 

Rose rose; 
Flower * pointer = &rose; 
rose.printFlower("red"); 

Lily lily; 
pointer = &lily; 
lily.printFlower("white"); // not sure what color lilies are 

Jasmine jas; 
pointer = &jas; 
jas.printFlower("orange"); 
return 0; 
} 

私の仕事は、ローズ、リリーとジャスミンのクラスでのパブリックアクセス修飾子を使用しないことですが、私がしたい場合、私は公に花を継承することができます。だから、これを達成するためにプライベートコンストラクタを使用する方法がありますか?

EDIT:私が提供した情報がどれほど少ないかを知ったので、ここで質問を編集しています。以下は私が変更できない花のスーパークラスの宣言です。

class Flower{ 
protected: 
    bool isPopular; 
    bool isThorny; 

public: 
    Flower(bool isPopular, bool isThorny){ 
     this->isPopular = isPopular; 
     this->isThorny = isThorny; 
    } 

    bool getIsPopular(){ 
     return this->isPopular; 
    } 

    bool getIsThorny(){ 
     return this->isThorny; 
    } 
    virtual string getColor() = 0; 

    void printFlower(string name){ 
     cout << "A " << name << " has '" << this->getColor() << "' color and is " 
    << (this->getIsThorny()?"":"not ") << "thorny, and is " << (this->getIsPopular()?"":"not ") 
    << "very popular." << endl; 
    } 
}; 

私の仕事は、画像内に、次の基本的である: Task for declaring derived-classes

タスクがちょうどメイン実行し、メインから呼び出された場合printFlower機能を印刷します。私が持っている唯一の制限は、Rose、Lily、Jasmineのクラス宣言の中でpublicアクセス修飾子を使うことができないということですが、私は花から公に継承することができます。すなわち、クラスRose:public Flower(){} Rose、Lily、Jasmineのメンバーを非公開にしたり、保護したりする方法はありますか?

+1

: 'struct'の代わりに使用したなど' Rose'、 'Lily'を定義します'class'とすると' public'キーワードを使う必要はありません。 – Jarod42

+3

冗談の解答を表示

struct Rose : Flower { Rose() : Flower(...) {} string getColor() const override { return "red"; } }; 
Angew

+2

これらのクラスのインスタンスを作成したいが、makeコンストラクタをパブリックにしたくない。それ以上の理由は「これはできますか?」? –

答えて

0

あなたは明らかにファクトリパターンを特定の方向に誘導しているようです。ソリューションは、インスタンス化を行うFlowerにファクトリ関数を定義することです。

これをどのように行うことができるかを示します。これは役に立つかもしれない、なぜ、私はコンパイル時の型に実行時パラメータから、単純な翻訳に工場を行います証明するために:

class Flower 
{ 
public: 
    virtual ~Flower() = default; 

    static std::unique_ptr<Flower> create(const std::string &species) 
    { 
    std::unique_ptr<Flower> result; 
    if (species == "rose") 
    { 
     result = std::make_unique<Rose>(); 
    } 
    else if (species == "lily") 
    { 
     result = std::make_unique<Lily>(); 
    } 
    else 
    { 
     throw std::invalid_argument("No such flower"); 
    } 
    return result; 
    } 
}; 

class Rose : public Flower 
{ 
    friend Flower; 
    Rose() = default; 
}; 

class Lily : public Flower 
{ 
    friend Flower; 
    Lily() = default; 
}; 


int main(int argc, char **argv) 
{ 
    auto rose = Flower::create("rose"); 
    auto lily = Flower::create("lily"); 
    auto whatTheUserRequested = Flower::create(argv[1]); 
} 
+0

私は基本クラスに派生したクラスを公開すべきではないと思います。したがって、あなたのファクトリメソッドは基底クラスにあるべきではありません。静的関数を持つ別のクラスである必要があります。 –

+0

@AbdusSalamKhazi状況によって異なります。サンプルのコードについては問題ありません。実際には、おそらく抽象的な工場があります。あるいは、派生クラスのリストが固定されていて、基本クラスがファクトリ関数を持っているという事実が、それらを知るのに十分な理由を与えている状況にあるかもしれません。 – Angew

+0

はQを編集しました。回答は – johndoe

0

ファクトリ関数を使って何か

このような
class FlowerFactory 
{ 
    Flower* getFlower(string flowerName) 
    { 
     if(flowerName == "Rose") 
     { 
      return new Rose(); 
     } 
     if(flowerName == "Lily") 
     { 
      return new Lily(); 
     } 
     if(flowerName == "Jasmine") 
     { 
      return new Jasmine(); 
     } 
    } 
} 

//Base class 
class Flower 
{ 
}; 

class Jasmine : public Flower 
{ 
    //other things here.. 

    friend FlowerFactory; 
}; 

class Rose : public Flower 
{ 
    //other things here.. 

    friend FlowerFactory; 
}; 

class Lily : public Flower 
{ 
    //other things here.. 

    friend FlowerFactory; 
}; 
+0

でした。質問を編集しました。答えをありがとう! – johndoe

0

はあなたですアクセス指示子を使用しないように指示するか、あなたのメンバーのどれもプライベートにすることができませんか?それが前者の場合は、classの代わりにstructを使用して、公開アクセスをデフォルトでにすることができます。たとえば、次のように

クラス `Flower` /` Rose`がより興味深いものになるだろう...
+0

私はたくさんの質問を編集しました – johndoe

+0

@johndoe唯一の制限は、パブリックアクセス指定子を使用できないということです。これは、すべてのメンバーが私的であるか保護されている必要があることを意味するものではありません。 'struct'のメンバは、デフォルトでpublicです。 –

関連する問題