简体   繁体   中英

How do I access a private constructor in a class from the main function in C++?

I have a program where I have a super-class called Flower and sub-classes Rose, Lily, Jasmine.

The flower protected members with 2 variables describing the feature of the flower and public members with getter functions and a pure-virtual function (called string getColor()) printing the color of the sub-class flower. It also has a public member function that prints the characteristic of each flower (void printFlower(string name)).

I am trying to implement the class for Rose, Lily and Jasmine and I have to do so without using the public access modifier in the class. So, everything in the class must either be protected or private (even the constructor). I know that Rose, Lily, and Jasmine publicly inherit from the parent class Flower.

In my main function, I have this:

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

My task is to not use the public access modifier in the Rose, Lily and Jasmine classes but I can publicly inherit Flower if I want to. So, is there any way to use a private Constructor (using Flower as a friend) or something like that to accomplish this?

EDIT: I realized how little info I provided so I am editing the question here. The following is the declaration for the Flower super-class which I cannot change.

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

My task is basically the following in the image: Task for declaring derived-classes

The task will just run main and print the printFlower function when called from main. The only restriction I have is that I cannot use the public access modifier inside the class declaration for Rose, Lily and Jasmine but I can and do inherit from flower publicly. ie. class Rose:public Flower(){} Is there any way I can write Rose, Lily and Jasmine by making all its members private or protected?

You're apparently being guided towards a certain take on the Factory pattern. The solution is to define a factory function in Flower which will do the instantiation.

I will show how this can be done. To demonstrate why this might be useful , I will make the factory into a simple translator from runtime parameters to a compile-time type:

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

Use a factory function something like this

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

Are your instructions to not use access specifiers, or that none of your members can be private? If it's the former, you can use struct instead of class to get public access by default . For example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM