Question

Please take a look at the following code (a code is worth a thousand words):

shape.hpp

class Shape {
public:
    double area() const;
private:
    class ShapeImpl;
    ShapeImpl* pimpl;
};

shape.cc

// ABS
class Shape::ShapeImpl {
public:
    double area() const = 0;
};


class Circle : public Shape::ShapeImpl { // error: Shape::ShapeImpl is private
public:
    double area() const {return pi*r*r;}
};


double Shape::area() const {
    return pimpl->area();
}

I know where the error comes from, but I'm more concerned with good practices. My questions:

  1. In the case of the above code, is mixing Pimpl with ABC a bad idea?

  2. if not, what is the best way to avoid the error (keeping encapsulation, etc.)?

  3. if yes, what I have to do to obtain polymorphism while hiding implementation from the user (in my Shape scenario)?

Obs: Assume that performance is not a problem.

Thank you.

Was it helpful?

Solution

  1. Its a fine idea. For reference, here is the letter/envelope idiom, due to Coplien. [ You can use an enum instead; obviously need to handle errors etc. The parallel being that the base type is public and the implementation hidden. See below.

  2. I'd just make the initial ShapeImpl declaration public; what problems does that cause?

See: example with a Shape

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top