2017-04-14 232 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'的成员默认是公共的。 –

相关问题