0

I got base class called Worker and two derived classes Merchant and Baker.

class Worker
{
private:
    string _name;
public:
    Worker(string, string, string, int);
    ~Worker();
    virtual string atributes() = 0;
};

class Merchant : public Worker
{
private:
    string _skillLevel;
public:
    Merchant(string, string);
    string atributes() override;
};

class Baker : public Worker
{
private:
    string yearsOfExperiance;
public:
    Baker(string, string);
    string atributes() override;
};

I have created list list<Workers> Workers and I am adding there Merchant and Baker objects like this:

void addToList(string name, string atributes, list<Worker>& Worker)
{
    if (name == "John")
    {
        Baker kk = Baker(name, atributes);
        Workers.push_front(kk);
    }
    else if (profesja == "Barack")
    {
        Merchant pp = merchant(name, atributes);
        Workers.push_front(pp);
    }
}

The problem is when I try to compile the code the C2259 error occurs. It says

'Worker': cannot instantiate absract class

Can you tell me how to solve this problem, please?

Da Artagnan
  • 1,109
  • 3
  • 17
  • 26
  • 1
    Your list holds a bunch of `Worker`s, right? But you can't have plain `Worker`s, only `Baker`s or `Merchant`s (that's what abstract means). So the list can't hold any `Worker`s in it. – user253751 Jan 20 '16 at 01:31

1 Answers1

1

You are trying to use polymorphism without using pointer or references, this doesn't work because object slicing would occur and object slicing requires to be able to construct the sliced type.

STL collections work by storying copies of the values, this means that here

 Baker kk = Baker(name, atributes);
 Workers.push_front(kk);

A Baker object is created on the stack, then you add to the collection, but the collection is templated to store Worker instances, so the method tries to construct a Worker instance from a Builder (which should be legal since a Builder is a Worker) through a copy constructor.

So basically what push_back is trying to do is sort of

Builder builder = Builder();
Worker worker = Worker(builder);

But this can't be done because Worker is abstract.

To solve the problem you must use pointers, possibly together with a smart pointer wrapper, eg:

std::vector<std::unique_ptr<Worker>> workers;
Jack
  • 131,802
  • 30
  • 241
  • 343