2017-04-14 231 views
1

我有一個程序,我有一個名爲花和子類玫瑰,莉莉,茉莉花的超級類。如何從C++的主函數訪問類中的私有構造函數?

花卉保護成員有2個描述花和公共成員功能的getter函數和一個純虛函數(稱爲字符串getColor()),用於打印子類花的顏色。它還有一個公共成員函數,可以打印每個花的特徵(void printFlower(string name))。

我想實現玫瑰,莉莉和茉莉花的類,我必須這樣做,而不使用類中的公共訪問修飾符。所以,類中的所有內容都必須被保護或私有(甚至是構造函數)。我知道Rose,Lily和Jasmine公開繼承了父類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; 
} 

我的任務是不使用的玫瑰,百合和茉莉花類公共訪問修飾符,但我可以公開繼承花,如果我想。那麼,有沒有辦法使用一個私人的構造函數(使用Flower作爲朋友)或類似的東西來實現這一點?

編輯:我意識到我提供的信息很少,所以我在這裏編輯問題。以下是我無法改變的Flower超級班的聲明。

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功能。我唯一的限制是我不能在玫瑰,莉莉和茉莉花的類聲明中使用公共訪問修飾符,但是我可以並且公開繼承花。即。上課玫瑰:public flower(){} 有沒有什麼辦法可以讓玫瑰,莉莉和茉莉花的所有成員變得私人或受保護?

+1

顯示類'Flower' /'Rose'會更有趣...... – Jarod42

+3

舌頭在臉頰的答案:使用'struct'而不是定義'Rose','Lily'等。 'class',那麼你不必使用'public'關鍵字。 – Angew

+2

所以你想創建這些類的實例,但你不想讓構造函數公開。除此之外的任何理由都可以做到嗎?「? –

回答

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

編輯問答感謝您的回答 – 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

是你的不使用訪問說明符的說明,或者您的所有成員都不能私人使用?如果是前者,則可以使用struct而不是class默認獲得公共訪問。例如:

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

我編輯了很多問題 – johndoe

+0

@johndoe你說你唯一的限制是你不能使用公共訪問說明符。這並不意味着您的所有成員都必須是私人的或受保護的。 'struct'的成員默認是公共的。 –

相關問題