What is the purpose of a virtual operator ()() here? - c++

I'm trying to modify code I found, but I'm blocked by my lack of understanding of the purpose, importance, and/or relevance of this virtual operator:
Can someone provide insight as to why this operator is necessary or useful?
Am I right in thinking it takes parentItem(), rect_, and resizer_ as parameters, then modifies the value of resizer_?
Constructor in .h:
virtual void operator()(QGraphicsItem* item, const QRectF& rect) = 0;
Call in .cpp:
(*resizer_)(parentItem(), rect_);
Trimmed context for the constructor for reference:
class SizeGripItem : public QGraphicsItem
{
private:
class HandleItem : public QGraphicsRectItem
{
public:
HandleItem(int positionFlags, SizeGripItem* parent);
private:
SizeGripItem* parent_;
};
public:
class Resizer
{
public:
virtual void operator()(QGraphicsItem* item,
const QRectF& rect) = 0;
};
SizeGripItem(Resizer* resizer = 0, QGraphicsItem* parent = 0);
virtual ~SizeGripItem();
private:
void doResize();
QRectF rect_;
Resizer* resizer_;
};

The Resizer is a broken attempt at a polymorphic functor (function object). Such an idiom was useful before C++11. It's broken because such functors are useless without a virtual destructor. It should have looked as follows:
class Resizer {
public:
virtual void operator()(QGraphicsItem* item, const QRectF& rect) = 0;
virtual ~Resizer() {}
};
Such objects are callable:
void invokeResizer(Resizer * resizer, QGraphicsItem * item, const QRectF & rect) {
(*resizer)(item, rect);
}
The above will execute the method operator()(QGraphicsItem*,const QRectF&) on the resizer object.
In modern code, instead of such hacks, one should use std::function<void(QGraphicsItem*, const QRectF &)>.

Regarding point 2, consider this line:
(*resizer_)(parentItem(), rect_);
resizer_ is likely a pointer to an object of an unknown type T, thus *resizer is a reference to an object of the same type T.
If it has a definition for operator() that accepts two parameters having types (let me say) decltype(parentItem()) and decltype(rect_), you can invoke it as it happens in the example.
In other terms, it's equivalent to:
resizer_->operator()(parentItem(), rect_);
It doesn't modify the value of resizer_ at all.
Can someone provide insight as to why this operator is necessary or useful?
Well, it mostly depends on the context and the actual problem it aims to solve.
It's hard to say from a line of code.
If you find it useless, don't use it. That's all.

Related

Avoid downcasting in an inherited tree class

I'm relatively new to C++ and I'm right now facing a point in my design where I cannot seem to avoid downcasting. I know this is usually a sign of bad design, so I would like to know what would be a better way to do this.
I have a class Frame that represents geometrical frame trees and allows geometrical transformations between them:
class Frame
{
private:
Frame *_parent;
std::vector<Frame*> _children;
public:
Frame* getParent() const;
std::vector<Frame*> getChildren() const;
... (extra methods for geometrical transformations)
}
I want now to create a new Frame subclass, MechanicalFrame, that adds some functionality to deal with dynamical properties.
class MechanicalFrame
{
private:
double mass;
...
public:
void compute();
}
My problem is that, the "compute" method needs to implement some recursive logic, so it would contain something like this:
MechanicalFrame::compute()
{
for element in getChildren():
element.compute();
}
However, since getChildren returns a vector of Frame* and not MechanicalFrame*, I would need to make a static_cast at this point. I've given the problem a lot of thought, but none of the solutions I've found are fully satisfying to me:
Solution 1) Static cast: somehow it indicates bad design
Solution 2) Add the compute method to the base class (Frame) with a dummy implementation, i.e., throwing an exception: it seems unnatural to force the implementation of the parent class based on the derived class.
Solution 3) Split totally MechanicalFrame from Frame: this would mean reimplementing many of the functionalities already available in Frame.
Any help would be very appreciated.
Many thanks in advance :)
Use polymorphic behaviour, use your Solution 2)
You can follow below pattern (Interface -> Base class -> Derived class)
class IFrame
{
public:
virtual void compute()=0;
}
class Frame:public IFrame
{
public:
virtual void compute() {/*nothing to do*/}
}
class MechanicalFrame:public Frame
{
public:
virtual void compute() {/*your implementation with mass*/}
}
If you are sure that all the Frame* pointers in MechanicalFrame::getChildren() are pointing to MechanicalFrame instances, I don't see any problem with static_cast. Make sure you use dynamic_cast + assert in debug builds to catch mistakes.
void MechanicalFrame::compute()
{
for(auto frame_ptr : getChildren())
{
downcast<MechanicalFrame*>(frame_ptr)->compute();
}
}
Where downcast is something like:
template <typename TOut, typename T>
auto downcast(T* ptr)
{
static_assert(std::is_base_of<T, TOut>{});
assert(ptr != nullptr);
assert(dynamic_cast<TOut>(ptr) == ptr);
return static_cast<TOut>(ptr);
}
(For a more thorough implementation of downcast see my Meeting C++ 2015 lightning talk "Meaningful casts" or my current implementation in vrm_core.)
Notice that there's a performance advantage here, as you avoid virtual dispatch. Play around with this snippet on gcc.godbolt.org to see differences in the generated assembly.
Another option is to use the Visitor pattern:
class Frame;
class MechanicalFrame;
class FrameVisitor
{
public:
virtual ~FrameVisitor() = default;
virtual void visit(Frame&) = 0;
virtual void visit(MechanicalFrame&) = 0;
};
class Frame
{
public:
virtual void accept(FrameVisitor& visitor)
{
visitor.visit(*this);
}
void acceptRecursive(FrameVisitor& visitor)
{
accept(visitor);
for (Frame* child : getChildren())
{
child->acceptRecursive(visitor);
}
}
...
};
class MechanicalFrame : public Frame
{
public:
virtual void accept(FrameVisitor& visitor) override
{
visitor.visit(*this);
}
...
};
Then the client code will be:
class ConcreteVisitor : public FrameVisitor
{
public:
virtual void visit(Frame& frame) override
{
// Deal with Frame (not a subclass) object.
}
virtual void visit(MechanicalFrame& frame) override
{
// Deal with MechanicalFrame object.
}
};
Frame root = ...;
ConcreteVisitor visitor;
root.acceptRecursive(visitor);
In general, the Visitor pattern allows you to traverse a hierarchy of heterogeneous objects and perform operations on them without type casting. It's most useful when the number of operations is expected to grow while your type hierarchy is more or less stable.
Since you're asking for new ideas, I will not explain in detail anything you written about in solutions 1-3.
You could add extra functionality to the MechanicalFrame class, splitting its children of MechanicalFrame class and all other classes, like this:
class Frame {
public:
std::vector<Frame*> getChildren(); // returns children
void addChild(Frame* child); // adds child to children
private:
std::vector<Frame*> children;
}
class MechanicalFrame : public Frame {
public:
void compute();
std::vector<MechanicalFrame*> getMechanicalChildren(); // returns mechanical_children
void addChild(MechanicalFrame* child); // adds child to mechanical_children
private:
std::vector<MechanicalFrame*> mechanical_children;
}
One possible implementation of compute is the following:
void MechanicalFrame::compute() {
...
for (auto* child : getMechanicalChildren()) {
child->compute();
}
}
UP: As far as I understand, one of the problems with casts is that the code starts behaving very differently depending on the actual class of the object, and we cannot substitute the parent class object with child class (see Liskov principle). The approach described in this answer actually changes the principle of using the "mechanicity" of your Frames, allowing adding MechanicalFrame children in such a way that they're ignored in compute method.

Does it cost to convert pointer to value in c++?

I am learning c++.
I learned when I should use 'pass by pointer' or 'pass by const reference' at google style guide.
It says
(1) if any members changes in a function, the value should be passed by pointer.
(2) if any members does not changed in a function, the value should be passed by const reference.
I wonder that when I have a pointer of a instance and any members will not change in a new function whether I need to make the function with pass by const reference to keep google style guide or not. If so, I need to convert the pointer to real value by '*pointer'. I am caring of the cost of conversion from pointer to real value but honestly I don't know whether it has cost or not. Please tell me how to do it in this situation.
This situation happens when I use visitor pattern. I need to use 'this' pointer but the members does not change in a function. I don't know whether there are any benefit or cost to keep google style guide in this situation.
In case, I copy sample code below. It is a part of visitor pattern. And it has two functions made with pass by pointer and pass by const reference.
#include <iostream>
class ClassA;
class VisitorInterface {
public:
virtual ~VisitorInterface() = default;
virtual void operator() (ClassA* obj) const = 0;
virtual void operator() (const ClassA& obj) const = 0;
};
class VisitorsHostInterface { // = visitor's host
public:
virtual ~VisitorsHostInterface() = default;
virtual void accept(VisitorInterface* v) = 0;
virtual void accept(const VisitorInterface& v) = 0;
};
class VisitorsHost : public VisitorsHostInterface {
public:
virtual ~VisitorsHost();
void accept(VisitorInterface* v) override {};
void accept(const VisitorInterface& v) override {};
};
class ClassA : public VisitorsHostInterface {
public:
void print() const { std::cout << "ClassA value_ = " << value_ << std::endl; }
void accept(VisitorInterface* v) override {
(*v)(this);
};
void accept(const VisitorInterface& v) override {
v(*this);
};
private:
int value_=11;
};
class Visitor : public VisitorInterface {
public:
virtual ~Visitor() = default;
void operator() (ClassA* obj) const override {
if (obj) {
obj->print();
}
}
void operator() (const ClassA& obj) const override {
obj.print();
}
};
In your case, no
You have two signatures
void accept(VisitorInterface* v) override {};
void accept(const VisitorInterface& v) override {};
They both expect a reference (or pointer and reference if you want to be exact), so you are not actually converting this to an object and in both cases you will just pass the address of this to each of the accept functions
However if you had
void accept(const VisitorInterface v) override {};
You could have invoked a copy-constructor which can be expensive, depending on what it does.
First, for the question you are asking, these is no difference between passing in *this and this from a performance standpoint when you have Thing * and const Thing & as the alternative overloads to select between.
But, your code has other confusions and problems. You have several different dimensions of visitation going on here, and I think you're confusing to orthogonal cases. Here are the cases as I see them:
You have a visitor that will be unchanged as it visits and the thing being visited will also not be changed.
You have a visitor that will be changed as it visits and the thing being visited will not be changed.
You have a visitor that will be unchanged as it visits and the thing being visited will be changed.
You have a visitor that will be changed as it visits and the thing being visited will also be changed.
I think you are confusing the cases of the thing being visited being changed, and the visitor changing as it visits things. If you weren't, you'd have four different accept methods all over the place instead of two, or the accept methods in the VisitorHostInterface and the VisitorInterface would have their const qualifiers in different spots.

How to pass class with virtual methods around and how to use it as member variable?

I've recently started unit testing my code, using Catch and Fakeit.
I have a wrapper class around the WinAPIs HWND.
class Window
{
public:
Window(HWND hwnd);
virtual void resize(int width, int height);
...
private:
HWND m_hwnd;
};
This and the tests for it work fine. For the tests I'm creating some actual
windows using WinAPI's CreateWindow(...).
However, I've stumbled upon a problem and I'm not sure what's the best solution to it.
In my code I just kept passing Window by value, since it's basically just the HWND anyway.
Some methods take it as const&, but when using it as class members, I usually just copied it.
class Foo
{
public:
Foo(const Window& window)
: m_window(window)
{}
private:
Window m_window;
};
Now lets assume I want to test Foo. I need to somehow stub the Window class, but I can only do that
if I am able to override virtual methods. I think you see the problem here.
class Foo
{
public:
Foo(const std::shared_ptr<Window>& window)
: m_window(window)
{
assert(m_window != nullptr);
}
private:
std::shared_ptr<Window> m_window;
};
I now spent the last two hours, refactoring all my code, so that I only pass std::shared_ptr and almost
never use the Window class by value. Foo now looks like this:
class
This makes sense, cause even if I pass the Window by value, it usually IS shared
anyway (if I resize it, it's resized for all instances).
However, I also felt that it complicated my code ALOT. For the comparison operator== I now always have to derefence
both sides. When I'm trying to find in an stl container, I now have to use
std::find_if(haystack.begin(), haystack.end(),[&needle](const SharedWindowPtr& ptr) { return *ptr == *needle; });
In addition to that, there's overhead from the shared_ptr. I also run the risk of passing nullptrs, where I want to ensure that doesn't happen. I can check that with assertions, but that isn't foolproof. I could also not pass a shared_ptr but a reference to Foo's constructor and give the Window class a std::unique_ptr<Window> clone() method, but I would have to mock that for every test and if there's a way around it I'd prefer that.
Now I'm wondering if there's any better/cleaner method for handling this kind of problem? Thanks for any advice on this.
EDIT: After thinking about this for a while, I had another idea to approach this.
class WindowHandler
{
public:
virtual void resize(int w, int h) = 0;
virtual void getTitle() = 0;
// ...
};
class DefaultWindowHandler
{
public:
DefaultWindowHandler(HWND hwnd);
virtual void resize(int w, int h) override
{
// ...
}
// ...
protected:
HWND m_hwnd;
};
class Window
{
public:
Window(HWND hwnd)
: m_windowHandler(new DefaultWindowHandler(hwnd))
{
// empty
}
void setWindowHandler(WindowHandler* handler)
{
assert(handler != nullptr);
m_windowHandler.reset(handler);
}
void resize(int w, int h)
{
m_windowHandler->resize(w, h);
}
};
What I like about this, is that I can pass the Window class around by value and still get the benefits of the interface-like behaviour if I need to. What do you think about that, what are the shortcomings? I know that the Window should probably accept a WindowHandler instead of the HWND as the constructor argument, but it's just easier to use the way it is.
Following what as been asked in the comment, it seems like std::unique_ptr will suffer from this option too. If taking by value of the base class, using any pointer or reference is not available, you can always use templates:
template<typename WindowType>
struct Foo {
// Want speed? take by value!
Foo(WindowType window)
: m_window(std::move(window))
{}
private:
WindowType m_window;
};
Then, your class will work with all subtypes of window. But then, using template, the functions being virtual or not is irrelevant.
If you want to limit your class Foo to only accept subtypes of windows, you have two choices: sfinae-like or static_assert
sfinae-like
template<typename, typename = void>
struct Foo;
template<typename WindowType>
struct Foo<WindowType, std::enable_if_t<std::is_base_of<Window, WindowType>::value>> {
Foo(WindowType window)
: m_window(std::move(window))
{}
private:
WindowType m_window;
};
static_assert
template<typename WindowType>
struct Foo {
static_assert(std::is_base_of<Window, WindowType>::value, "WindowType must be a subclass of Window");
Foo(WindowType window)
: m_window(std::move(window))
{}
private:
WindowType m_window;
};
The sfinae-like method will have the advantage of being able to "overload" your class for other types that matches with other conditions, but the static_assert is slightly easier to implement.

PIMPL problem: How to have multiple interfaces to the impl w/o code duplication

I have this pimpl design where the implementation classes are polymorphic but the interfaces are supposed to just contain a pointer, making them polymorphic somewhat defeats the purpose of the design.
So I create my Impl and Intf base classes to provide reference counting. And then the user can create their implementations. An example:
class Impl {
mutable int _ref;
public:
Impl() : _ref(0) {}
virtual ~Impl() {}
int addRef() const { return ++_ref; }
int decRef() const { return --_ref; }
};
template <typename TImpl>
class Intf {
TImpl* impl;
public:
Intf(TImpl* t = 0) : impl(0) {}
Intf(const Intf& other) : impl(other.impl) { if (impl) impl->addRef(); }
Intf& operator=(const Intf& other) {
if (other.impl) other.impl->addRef();
if (impl && impl->decRef() <= 0) delete impl;
impl = other.impl;
}
~Intf() { if (impl && impl->decRef() <= 0) delete impl; }
protected:
TImpl* GetImpl() const { return impl; }
void SetImpl(... //etc
};
class ShapeImpl : public Impl {
public:
virtual void draw() = 0;
};
class Shape : public Intf<ShapeImpl> {
public:
Shape(ShapeImpl* i) : Intf<ShapeImpl>(i) {}
void draw() {
ShapeImpl* i = GetImpl();
if (i) i->draw();
}
};
class TriangleImpl : public ShapeImpl {
public:
void draw();
};
class PolygonImpl : public ShapeImpl {
public:
void draw();
void addSegment(Point a, Point b);
};
Here is where have the issue. There are two possible declaration for class Polygon:
class Polygon1 : public Intf<PolygonImpl> {
public:
void draw() {
PolygonImpl* i = GetImpl();
if (i) i->draw();
}
void addSegment(Point a, Point b) {
PolygonImpl* i = GetImpl();
if (i) i->addSegment(a,b);
}
};
class Polygon2 : public Shape {
void addSegment(Point a, Point b) {
ShapeImpl* i = GetImpl();
if (i) dynamic_cast<Polygon*>(i)->addSegment(a,b);
}
}
In the Polygon1, I have rewrite the code for draw because I have not inherited it. In Polygon2 I need ugly dynamic casts because GetImpl() doesn't know about PolygonImpl. What I would like to do is something like this:
template <typename TImpl>
struct Shape_Interface {
void draw() {
TImpl* i = GetImpl();
if (i) i->draw();
}
};
template <typename TImpl>
struct Polygon_Interface : public Shape_Interface<Timpl> {
void addSegment(Point a, Point b) { ... }
};
class Shape : public TIntf<ShapeImpl>, public Shape_Interface<ShapeImpl> {...};
class Polygon : public TIntf<PolygonImpl>, public Polygon_Interface<PolygonImpl> {
public:
Polygon(PolygonImpl* i) : TIntf<PolygonImpl>(i) {}
};
But of course there's a problem here. I can't access GetImpl() from the Interface classes unless I derive them from Intf. And if I do that, I need to make Intf virtual everywhere it appears.
template <typename TImpl>
class PolygonInterface : public virtual Intf<TImpl> { ... };
class Polygon : public virtual Intf<PolygonImpl>, public PolygonInterface { ... }
OR I can store a TImpl*& in each Interface and construct them with a reference to the base Intf::impl. But that just means I have a pointer pointing back into myself for every interface included.
template <typename TImpl>
class PolygonInterface {
TImpl*& impl;
public:
PolygonInterface(TImpl*& i) : impl(i) {}
...};
Both of these solutions bloat the Intf class, add an extra dereference, and basically provide no benefit over straight polymorphism.
So, the question is, is there a third way, that I've missed that would solve this issue besides just duplicating the code everywhere (with its maintenance issues)?
TOTALLY SHOULD, BUT DOESN'T WORK: I wish there were base classes unions that just overlaid the class layouts and, for polymorphic classes, required that they have the exact same vtable layout. Then both Intf and ShapeInterface would each declare a single T* element and access it identically:
class Shape : public union Intf<ShapeImpl>, public union ShapeInterface<ShapeImpl> {};
I should note that your Impl class is nothing more than the reimplementation of a shared_ptr without the thread safety and all those cast bonuses.
Pimpl is nothing but a technic to avoid needless compile-time dependencies.
You do not need to actually know how a class is implemented to inherit from it. It would defeat the purpose of encapsulation (though your compiler does...).
So... I think that you are not trying to use Pimpl here. I would rather think this is a kind of Proxy patterns, since apparently:
Polygon1 numberOne;
Polygon2 numberTwo = numberOne;
numberTwo.changeData(); // affects data from numberOne too
// since they point to the same pointer!!
If you want to hide implementation details
Use Pimpl, but the real one, it means copying in depth during copy construction and assignment rather than just passing the pointer around (whether ref-counted or not, though ref-counted is preferable of course :) ).
If you want a proxy class
Just use a plain shared_ptr.
For inheritance
It does not matter, when you inherit from a class, how its private members are implemented. So just inherit from it.
If you want to add some new private members (usual case), then:
struct DerivedImpl;
class Derived: public Base // Base implemented with a Pimpl
{
public:
private:
std::shared_ptr<DerivedImpl> _data;
};
There is not much difference with classic implementation, as you can see, just that there is a pointer in lieu of a bunch of data.
BEWARE
If you forward declare DerivedImpl (which is the goal of Pimpl), then the destructor automatically generated by the compiler is... wrong.
The problem is that in order to generate the code for the destructor, the compiler needs the definition of DerivedImpl (ie: a complete type) in order to know how to destroy it, since a call to delete is hidden in the bowels of shared_ptr. However it may only generate a warning at compilation time (but you'll have a memory leak).
Furthermore, if you want an in-depth copy (rather than a shallow one, which consists in the copy and the original both pointing to the same DerivedImpl instance), you will also have to define manually the copy-constructor AND the assignment operator.
You may decide to create a better class that shared_ptr which will have deep-copy semantics (which could be called member_ptr as in cryptopp, or just Pimpl ;) ). This introduce a subtle bug though: while the code generated for the copy-constructor and the assignement operator could be thought of as correct, they are not, since once again you need a complete type (and thus the definition of DerivedImpl), so you will have to write them manually.
This is painful... and I'm sorry for you.
EDIT: Let's have a Shape discussion.
// Shape.h
namespace detail { class ShapeImpl; }
class Shape
{
public:
virtual void draw(Board& ioBoard) const = 0;
private:
detail::ShapeImpl* m_impl;
}; // class Shape
// Rectangle.h
namespace detail { class RectangleImpl; }
class Rectangle: public Shape
{
public:
virtual void draw(Board& ioBoard) const;
size_t getWidth() const;
size_t getHeight() const;
private:
detail::RectangleImpl* m_impl;
}; // class Rectangle
// Circle.h
namespace detail { class CircleImpl; }
class Circle: public Shape
{
public:
virtual void draw(Board& ioBoard) const;
size_t getDiameter() const;
private:
detail::CircleImpl* m_impl;
}; // class Circle
You see: neither Circle nor Rectangle care if Shape uses Pimpl or not, as its name implies, Pimpl is an implementation detail, something private that is not shared with the descendants of the class.
And as I explained, both Circle and Rectangle use Pimpl too, each with their own 'implementation class' (which can be nothing more than a simple struct with no method by the way).
I think you were right in that I didn't understand your question initially.
I think you're trying to force a square shape into a round hole... it don't quite fit C++.
You can force that your container holds pointers to objects of a given base-layout, and then allow objects of arbitrary composition to be actually pointed to from there, assuming that you as a programmer only actually place objects that in fact have identical memory layouts (member-data - there's no such thing as member-function-layout for a class unless it has virtuals, which you wish to avoid).
std::vector< boost::shared_ptr<IShape> > shapes;
NOTE at the absolute MINIMUM, you must still have a virtual destructor defined in IShape, or object deletion is going to fail miserably
And you could have classes which all take a pointer to a common implementation core, so that all compositions can be initialized with the element that they share (or it could be done statically as a template via pointer - the shared data).
But the thing is, if I try to create an example, I fall flat the second I try to consider: what is the data shared by all shapes? I suppose you could have a vector of Points, which then could be as large or small as any shape required. But even so, Draw() is truly polymorphic, it isn't an implementation that can possibly be shared by multiple types - it has to be customized for various classifications of shapes. i.e. a circle and a polygon cannot possibly share the same Draw(). And without a vtable (or some other dynamic function pointer construct), you cannot vary the function called from some common implementation or client.
Your first set of code is full of confusing constructs. Maybe you can add a new, simplified example that PURELY shows - in a more realistic way - what you're trying to do (and ignore the fact that C++ doesn't have the mechanics you want - just demonstrate what your mechanic should look like).
To my mind, I just don't get the actual practical application, unless you're tyring to do something like the following:
Take a COM class, which inherits from two other COM Interfaces:
class MyShellBrowserDialog : public IShellBrowser, public ICommDlgBrowser
{
...
};
And now I have a diamond inheritence pattern: IShellBrowser inherits ultimately from IUnknown, as does ICommDlgBrowser. But it seems incredibly silly to have to write my own IUnknown:AddRef and IUnknown::Release implementation, which is a highly standard implementation, because there's no way to cause the compiler to let another inherited class supply the missing virtual functions for IShellBrowser and/or ICommDlgBrowser.
i.e., I end up having to:
class MyShellBrowserDialog : public IShellBrowser, public ICommDlgBrowser
{
public:
virtual ULONG STDMETHODCALLTYPE AddRef(void) { return ++m_refcount; }
virtual ULONG STDMETHODCALLTYPE Release(void) { return --m_refcount; }
...
}
because there's no way I know of to "inherit" or "inject" those function implementations into MyShellBrowserDialog from anywhere else which actually fill-in the needed virtual member function for either IShellBrowser or ICommDlgBrowser.
I can, if the implementations were more complex, manually link up the vtable to an inherited implementor if I wished:
class IUnknownMixin
{
ULONG m_refcount;
protected:
IUnknonwMixin() : m_refcount(0) {}
ULONG AddRef(void) { return ++m_refcount; } // NOTE: not virutal
ULONG Release(void) { return --m_refcount; } // NOTE: not virutal
};
class MyShellBrowserDialog : public IShellBrowser, public ICommDlgBrowser, private IUnknownMixin
{
public:
virtual ULONG STDMETHODCALLTYPE AddRef(void) { return IUnknownMixin::AddRef(); }
virtual ULONG STDMETHODCALLTYPE Release(void) { return IUnknownMixin::Release(); }
...
}
And if I needed the mix-in to actually refer to the most-derived class to interact with it, I could add a template parameter to IUnknownMixin, to give it access to myself.
But what common elements could my class have or benefit by that IUnknownMixin couldn't itself supply?
What common elements could any composite class have that various mixins would want to have access to, which they needed to derive from themselves? Just have the mixins take a type parameter and access that. If its instance data in the most derived, then you have something like:
template <class T>
class IUnknownMixin
{
T & const m_outter;
protected:
IUnknonwMixin(T & outter) : m_outter(outter) {}
// note: T must have a member m_refcount
ULONG AddRef(void) { return ++m_outter.m_refcount; } // NOTE: not virtual
ULONG Release(void) { return --m_outter.m_refcount; } // NOTE: not virtual
};
Ultimately your question remains somewhat confusing to me. Perhaps you could create that example that shows your preferred-natural-syntax that accomplishes something clearly, as I just don't see that in your initial post, and I can't seem to sleuth it out from toying with these ideas myself.
I have seen lots of solutions to this basic conundrum: polymorphism + variation in interfaces.
One basic approach is to provide a way to query for extended interfaces - so you have something along the lines of COM programming under Windows:
const unsigned IType_IShape = 1;
class IShape
{
public:
virtual ~IShape() {} // ensure all subclasses are destroyed polymorphically!
virtual bool isa(unsigned type) const { return type == IType_IShape; }
virtual void Draw() = 0;
virtual void Erase() = 0;
virtual void GetBounds(std::pair<Point> & bounds) const = 0;
};
const unsigned IType_ISegmentedShape = 2;
class ISegmentedShape : public IShape
{
public:
virtual bool isa(unsigned type) const { return type == IType_ISegmentedShape || IShape::isa(type); }
virtual void AddSegment(const Point & a, const Point & b) = 0;
virtual unsigned GetSegmentCount() const = 0;
};
class Line : public IShape
{
public:
Line(std::pair<Point> extent) : extent(extent) { }
virtual void Draw();
virtual void Erase();
virtual void GetBounds(std::pair<Point> & bounds);
private:
std::pair<Point> extent;
};
class Polygon : public ISegmentedShape
{
public:
virtual void Draw();
virtual void Erase();
virtual void GetBounds(std::pair<Point> & bounds);
virtual void AddSegment(const Point & a, const Point & b);
virtual unsigned GetSegmentCount() const { return vertices.size(); }
private:
std::vector<Point> vertices;
};
Another option would be to make a single richer base interface class - which has all the interfaces you need, and then to simply define a default, no-op implementation for those in the base class, which returns false or throws to indicate that it isn't supported by the subclass in question (else the subclass would have provided a functional implementation for this member function).
class Shape
{
public:
struct Unsupported
{
Unsupported(const std::string & operation) : bad_op(operation) {}
const std::string & AsString() const { return bad_op; }
std::string bad_op;
};
virtual ~Shape() {} // ensure all subclasses are destroyed polymorphically!
virtual void Draw() = 0;
virtual void Erase() = 0;
virtual void GetBounds(std::pair<Point> & bounds) const = 0;
virtual void AddSegment(const Point & a, const Point & b) { throw Unsupported("AddSegment"); }
virtual unsigned GetSegmentCount() const { throw Unsupported("GetSegmentCount"); }
};
I hope that this helps you to see some possibilities.
Smalltalk had the wonderful attribute of being able to ask the meta-type-system whether a given instance supported a particular method - and it supported having a class-handler that could execute anytime a given instance was told to perform an operation it didn't support - along with what operation that was, so you could forward it as a proxy, or you could throw a different error, or simply quietly ignore that operation as a no-op).
Objective-C supports all of those same modalities as Smalltalk! Very, very cool things can be accomplished by having access to the type-system at runtime. I assume that .NET can pull of some crazy cool stuff along those lines (though I doubt that its nearly as elegant as Smalltalk or Objective-C, from what I've seen).
Anyway, ... good luck :)

Looking for a better way than virtual inheritance in C++

OK, I have a somewhat complicated system in C++. In a nutshell, I need to add a method to a third party abstract base class. The third party also provides a ton of derived classes that also need the new functionality.
I'm using a library that provides a standard Shape interface, as well as some common shapes.
class Shape
{
public:
Shape(position);
virtual ~Shape();
virtual position GetPosition() const;
virtual void SetPosition(position);
virtual double GetPerimeter() const = 0;
private: ...
};
class Square : public Shape
{
public:
Square(position, side_length);
...
};
class Circle, Rectangle, Hexagon, etc
Now, here's my problem. I want the Shape class to also include a GetArea() function. So it seems like I should just do a:
class ImprovedShape : public virtual Shape
{
virtual double GetArea() const = 0;
};
class ImprovedSquare : public Square, public ImprovedShape
{
...
}
And then I go and make an ImprovedSquare that inherits from ImprovedShape and Square. Well, as you can see, I have now created the dreaded diamond inheritance problem. This would easily be fixed if the third party library used virtual inheritance for their Square, Circle, etc. However, getting them to do that isn't a reasonable option.
So, what do you do when you need to add a little functionality to an interface defined in a library? Is there a good answer?
Thanks!
Why does this class need to derive from shape?
class ImprovedShape : public virtual Shape
{
virtual double GetArea() const = 0;
};
Why not just have
class ThingWithArea
{
virtual double GetArea() const = 0;
};
ImprovedSquare is a Shape and is a ThingWithArea
We had a very similar problem in a project and we solved it by just NOT deriving ImprovedShape from Shape. If you need Shape functionality in ImprovedShape you can dynamic_cast, knowing that your cast will always work. And the rest is just like in your example.
I suppose the facade pattern should do the trick.
Wrap the 3rd party interface into an interface of your own, and your application's code works with the wrapper interface rather than the 3rd party interface. That way you've nicely insulated changes in the uncontrolled 3rd party interface as well.
Perhaps you should read up on proper inheritance, and conclude that ImprovedShape does not need to inherit from Shape but instead can use Shape for its drawing functionality, similar to the discussion in point 21.12 on that FAQ on how a SortedList doesn't have to inherit from List even if it wants to provide the same functionality, it can simply use a List.
In a similar fashion, ImprovedShape can use a Shape to do it's Shape things.
Possibly a use for the decorator pattern? [http://en.wikipedia.org/wiki/Decorator_pattern][1]
Is it possible to do a completely different approach - using templates and meta-programming techniques? If you're not constrained to not using templates, this could provide an elegant solution. Only ImprovedShape and ImprovedSquare change:
template <typename ShapePolicy>
class ImprovedShape : public ShapePolicy
{
public:
virtual double GetArea();
ImprovedShape(void);
virtual ~ImprovedShape(void);
protected:
ShapePolicy shape;
//...
};
and the ImprovedSquare becomes:
class ImprovedSquare : public ImprovedShape<Square>
{
public:
ImprovedSquare(void);
~ImprovedSquare(void);
// ...
};
You'll avoid the diamond inheritance, getting both the inheritance from your original Shape (through the policy class) as well as the added functionality you want.
Another take on meta-programming/mixin, this time a bit influenced by traits.
It assumes that calculating area is something you want to add based on exposed properties; you could do something which kept with encapsulation, it that is a goal, rather than modularisation. But then you have to write a GetArea for every sub-type, rather than using a polymorphic one where possible. Whether that's worthwhile depends on how committed you are to encapsulation, and whether there are base classes in your library you could exploit common behaviour of, like RectangularShape below
#import <iostream>
using namespace std;
// base types
class Shape {
public:
Shape () {}
virtual ~Shape () { }
virtual void DoShapyStuff () const = 0;
};
class RectangularShape : public Shape {
public:
RectangularShape () { }
virtual double GetHeight () const = 0 ;
virtual double GetWidth () const = 0 ;
};
class Square : public RectangularShape {
public:
Square () { }
virtual void DoShapyStuff () const
{
cout << "I\'m a square." << endl;
}
virtual double GetHeight () const { return 10.0; }
virtual double GetWidth () const { return 10.0; }
};
class Rect : public RectangularShape {
public:
Rect () { }
virtual void DoShapyStuff () const
{
cout << "I\'m a rectangle." << endl;
}
virtual double GetHeight () const { return 9.0; }
virtual double GetWidth () const { return 16.0; }
};
// extension has a cast to Shape rather than extending Shape
class HasArea {
public:
virtual double GetArea () const = 0;
virtual Shape& AsShape () = 0;
virtual const Shape& AsShape () const = 0;
operator Shape& ()
{
return AsShape();
}
operator const Shape& () const
{
return AsShape();
}
};
template<class S> struct AreaOf { };
// you have to have the declaration before the ShapeWithArea
// template if you want to use polymorphic behaviour, which
// is a bit clunky
static double GetArea (const RectangularShape& shape)
{
return shape.GetWidth() * shape.GetHeight();
}
template <class S>
class ShapeWithArea : public S, public HasArea {
public:
virtual double GetArea () const
{
return ::GetArea(*this);
}
virtual Shape& AsShape () { return *this; }
virtual const Shape& AsShape () const { return *this; }
};
// don't have to write two implementations of GetArea
// as we use the GetArea for the super type
typedef ShapeWithArea<Square> ImprovedSquare;
typedef ShapeWithArea<Rect> ImprovedRect;
void Demo (const HasArea& hasArea)
{
const Shape& shape(hasArea);
shape.DoShapyStuff();
cout << "Area = " << hasArea.GetArea() << endl;
}
int main ()
{
ImprovedSquare square;
ImprovedRect rect;
Demo(square);
Demo(rect);
return 0;
}
Dave Hillier's approach is the right one. Separate GetArea() into its own interface:
class ThingWithArea
{
public:
virtual double GetArea() const = 0;
};
If the designers of Shape had done the right thing and made it a pure interface,
and the public interfaces of the concrete classes were powerful enough, you could
have instances of concrete classes as members. This is how you get SquareWithArea
(ImprovedSquare is a poor name) being a Shape and a ThingWithArea:
class SquareWithArea : public Shape, public ThingWithArea
{
public:
double GetPerimeter() const { return square.GetPerimeter(); }
double GetArea() const { /* do stuff with square */ }
private:
Square square;
};
Unfortunately, the Shape designers put some implementation into Shape, and you
would end up carrying two copies of it per SquareWithArea, just like in
the diamond you originally proposed.
This pretty much forces you into the most tightly coupled, and therefore least
desirable, solution:
class SquareWithArea : public Square, public ThingWithArea
{
};
These days, it's considered bad form to derive from concrete classes in C++.
It's hard to find a really good explanation why you shouldn't. Usually, people
cite Meyers's More Effective C++ Item 33, which points out the impossibility
of writing a decent operator=() among other things. Probably, then, you should
never do it for classes with value semantics. Another pitfall is where the
concrete class doesn't have a virtual destructor (this is why you should
never publicly derive from STL containers). Neither applies here. The poster
who condescendingly sent you to the C++ faq to learn about inheritance is
wrong - adding GetArea() does not violate Liskov substitutability. About
the only risk I can see comes from overriding virtual functions in the
concrete classes, when the implementer later changes the name and silently breaks
your code.
In summary, I think you can derive from Square with a clear conscience.
(As a consolation, you won't have to write all the forwarding functions for
the Shape interface).
Now for the problem of functions which need both interfaces. I don't like
unnecessary dynamic_casts. Instead, make the function take references to
both interfaces and pass references to the same object for both at the call site:
void PrintPerimeterAndArea(const Shape& s, const ThingWithArea& a)
{
cout << s.GetPerimeter() << endl;
cout << a.GetArea() << endl;
}
// ...
SquareWithArea swa;
PrintPerimeterAndArea(swa, swa);
All PrintPerimeterAndArea() needs to do its job is a source of perimeter and a
source of area. It is not its concern that these happen to be implemented
as member functions on the same object instance. Conceivably, the area could
be supplied by some numerical integration engine between it and the Shape.
This gets us to the only case where I would consider passing in one reference
and getting the other by dynamic_cast - where it's important that the two
references are to the same object instance. Here's a very contrived example:
void hardcopy(const Shape& s, const ThingWithArea& a)
{
Printer p;
if (p.HasEnoughInk(a.GetArea()))
{
s.print(p);
}
}
Even then, I would probably prefer to send in two references rather than
dynamic_cast. I would rely on a sane overall system design to eliminate the
possibility of bits of two different instances being fed to functions like this.
GetArea() need not be a member. It could be templated function, so that you can invoke it for any Shape.
Something like:
template <class ShapeType, class AreaFunctor>
int GetArea(const ShapeType& shape, AreaFunctor func);
The STL min, max functions can be thought of as an analogy for your case. You can find a min and max for an array/vector of objects given a comparator function. Like wise, you can derive the area of any given shape provided the function to compute the area.
There exists a solution to your problem, as I understood the question. Use the addapter-pattern. The adapter pattern is used to add functionality to a specific class or to exchange particular behaviour (i.e. methods). Considering the scenario you painted:
class ShapeWithArea : public Shape
{
protected:
Shape* shape_;
public:
virtual ~ShapeWithArea();
virtual position GetPosition() const { return shape_->GetPosition(); }
virtual void SetPosition(position) { shape_->SetPosition(); }
virtual double GetPerimeter() const { return shape_->GetPerimeter(); }
ShapeWithArea (Shape* shape) : shape_(shape) {}
virtual double getArea (void) const = 0;
};
The Adapter-Pattern is meant to adapt the behaviour or functionality of a class. You can use it to
change the behaviour of a class, by not forwarding but reimplementing methods.
add behaviour to a class, by adding methods.
How does it change behaviour? When you supply an object of type base to a method, you can also supply the adapted class. The object will behave as you instructed it to, the actor on the object will only care about the interface of the base class. You can apply this adaptor to any derivate of Shape.