mehdi mehdi - 4 months ago 6
C++ Question

How do i use an Abstract Class in other class (or any class)?

I know about Virtual Class that they cannot be instantiated, Now I have a question about a case about it, suppose we have a pure abstract class like below:

class Color{
public:
Color();
virtual string getName()=0;
~Color();
};


and 2 class inherited form it:

class Blue:public Color
{
public:
Blue();
~Blue();
string getName();
};

class Red:public Color{
public:
Red();
~Red();
string getName();
};


and third class want use
Color
class as its constructor parameter and data member:

class Foo{
public:
Foo();
Foo(Color&);
~Foo();
void draw(Color&);
private:
Color* co;
};


and its implementation:

Foo::Foo():co(new Color()){
}

Foo::Foo(Color &c):co(new Color(c)){
}


Now, I know about this part
new Color()
and
new Color(c)
is wrong in this case, but i want only to use a type
Color
to passed to
Foo
and not directly using
Blue
or
Red
as parameter.

what is solution? do i must using overloading or other thing? and for method
draw
do i have any problem?
and i read about Design Pattern, does it help me about this case?

tnx for your response.

ROX ROX
Answer

For the constructor that takes a Color&, you can either store a reference or pointer to the passed in color if you can be sure its going to continue to exist, or a smart pointer might be suitable for your use if you want to store a pointer to a previously existing color and ensure its not deleted too soon. Or if you want your class to hold its own copy of the color you can use the clone pattern. A copy constructor for color would have to return a color (not a class derived from it) which is not possible since color is abstract. Clone would be a virtual function in color returning a color pointer. In derived classes it is implemented to return a new instance of the derived type.

class Color
{
    public:
    virtual Color* Clone() const = 0;
};

class Red : public Color
{
    public:
    virtual Red* Clone() const
    {
        return new Red();
    }
};

Foo::Foo(const Color& c) : co(c.Clone())
{}

For the default foo constructor you need to choose whether its OK for foo's color* member to be null, if it is then pass in nullptr as suggested. If not you can pick a default color to initialise the color*. Note Foo still holds a color* not a Red*. You could specify the default color class with a typedef or using statement, to ensure that you define the default only once:-

using DefaultColour = Red;
Foo::Foo() : co(new DefaultColour()) {}

Or just don't give Foo a default construct - insist that a Color is provided

Comments