How to share code between two classes having same parent? - c++

Although I am using MFC, I believe this is primarily a C++ question.
I have CResizingDialog derived from CDialog which is the base class for all my dialogs in the application. It gives them the ability to automatically (you guessed it) resize according to target screen size. CResizingDialog achieves this by overrides CDialog's several virtual functions including OnSize(), OnInitDialog(), OnPaint(). So far well and good.
Now I am adding a property sheet/page which also needs the same resizing functionality however I can't use CResizingDialog as base class for my property page. This means I will need a new base class say CResizingPage derived from CPropertyPage which will contain same functionality as CResizingDialog.
However the code that resizes the dialogs and its controls is exactly the same. Is there a way I can reuse the CResizingDialog somehow? I have never used multiple inheritance, will that help here?

I have 2 suggestions how to solve this, you'll have to decide which is easier/nicer for your situation.
If possible you can move the resizing code into a standalone function with the appropriate parameters that you can call from your 2 virtual functions.
The other way is to make the base class a template. Something like this:
template< typename Base >
CResizingBase
: public Base
{
// override the appropriate functions here
};
class CResizingDialog
: public CResizingBase< CDialog >
{
};
class CResizingPage
: public CResizingBase< CPropertyPage >
{
};

Related

Strategy pattern Qt ambiguous base

For a school project we have to make a 'game', in this game we visualize a maze and find our way through it. This visualization has to be possible in two different ways, in our case a text-based visualization and a more fancy way.
We have to use Qt for this, we are using a QMainWindow with a QWidget in it, this widget will be one or the other visualization. Seeing that during the game we should be able to switch between visualizations, we use the Strategy Pattern, so made an interface (ViewInterface) and both visualizations implement this. Beside implementing ViewInterface, both visualizations inherit another class, in the text-based this is QPlainTextEdit (to have a QWidget with text) and in the Fancy this is QDialog. Probem here is that in my controller, I have a pointer to a ViewInterface which is used to fill the QWidet but to do this ViewInterface also has to inherit from QWidget, which causes this error: QObject is an ambiguous base of 'TerminalView'.
Since the switching between views can be done while playing the game, and update should be called only on the currently-active view, we can't pass the specific view to 'setWidget'.
Am I doing something wrong or how can I solve this? (I already thought about it but can't come with solutions).
The problem here is that you inherit QObject twice: first in ViewInterface hierarchy, second in QDialog hierarchy (diamond problem). Try using virtual inheritance for your FancyView and TextView classes (DOES NOT WORK, SINCE VIRTUAL INHERITANCE SHOULD BE USED IN ENTIRE HIERARCHY)
But there is another problem with your design: both QDialog and QPlainTextEdit inherit QWidget. To resolve this issue you may do the following:
Make ViewInterface abstract without inheriting from QObject. This abstract class will define the interface of your FancyView and TextView and may or may not implement some common logic.
Implement FancyView and TextView with multiple inheritance from QDialog and ViewInterface and from QPlainTextEdit and ViewInterface respectively.
This way you may not encounter any problems with ambiguous base class.
UPDATE:
Did not see your edit yet: indeed this would solve the issue, but
another problem rises: if I do this, I can't use a ViewInterface
pointer to set my QWidget. It is possible indeed, but in my opinion
this is not really clean
Well, that is a real problem. An obvious solution is not to use ViewInterface* instead of QWidget*. But this means that you need to change quite a lot of code and it may actually be not that great in your case.
With respect to the given comment, I propose another solution:
Inherit ViewInterface from QWidget (with all desired interface functions):
class ViewInterface: public QWidget {
Q_OBJECT
...
}
In ViewInterface constructor set layout to be used by widget and set it up:
ViewInterface::ViewInterface (QWidget* i_parent)
: QWidget (i_parent) {
auto layout {new QGridLayout (this)};
// Zeroed margins to make full fit.
layout->setContentsMargins (0, 0, 0, 0);
setLayout (layout);
}
In constructors of derived classes add specific widget to layout:
class FancyView : public ViewInterface {
Q_OBJECT
FancyView (QWidget* i_parent)
: ViewInterface (i_parent)
, dialog_widget_ {new QDialog (this)} {
layout->addWidget (dialog_widget_);
}
...
private:
QDialog* dialog_widget_;
}
Implement desired interface using target widget. If you want to process events, you may use QObject::eventFilter (). In this case you should set your FancyView object from the code above as event filter for dialog_widget_.
NOTE: In this case you can not use FancyView as QDialog. A workabound for this issue is proxy QDialog signals, slots and public functions and create yet another wrapper class FancyViewDialog, that works as proxy for the methods, signals and slots in FancyView. That is not a fantastic solution, but I do not see any other way around diamond problem that allows "is-a" relation between ViewInterface and QWidget.
An interface should be abstract with virtual methods and have no concrete base classes. ViewInterface should not inherit from QWidget. That fixes your problem.
Now there are at least two solutions to converting the ViewInterface instance to QWidget:
Template the users of ViewInterface and have them ensure that the concrete type used does in fact derive from QWidget. That will work if the type is there's no runtime polymorphism.
If there's runtime polymorphism, add a QWidget * widget() = 0 method to the interface, and implement it in the derived methods. It's trivial: QWidget * widget() override { return this; }.
The interface can have both signals and slots - they must be virtual methods, but they certainly will work. See e.g. this answer to get started with virtual signals.
If you want to share some code between the two concrete implementations of ViewInterface, you can have an additional class that derives from ViewInterface to provide the shared code. Both TerminalView and FancyView would derive from that class. The helper class could be parametrized on the base class type, to have it jump through less hoops to access the widget, e.g.: class TerminalView : ViewHelper<QPlainTextEdit> { ... };

can an abstract class inherit from a "normal" class?

I am looking for a useful example of multiple inheritance in C++ and found an example for Window-creation here: A use for multiple inheritance? and modified it a bit. It conceptually looks like this:
class Window
class Skinable // abstract
class Draggable // abstract
class DraggableSkinnableWindow : Window, Draggable, Skinnable
I think this is supposed to be a good example where MI makes sense. Since it doesn't make sense to implement a class of Skinable, it should be defined abstract.
Now: How would this look like if I would not use the concept of MI.
I would have used a simple hierarchical structure like this:
class Window
class Dragable : public Window
class Skinable : public Dragable
class DraggableSkinnableWindow : Skinnable
I still want Dragable and Skinable to be abstract as well but is that even possible? Is the second example even a good solution for the same context but not using MI?
Thank you in advance!
While your example is a solid use case for multiple inheritance, I disagree with the assertion that it does not make sense for Skinnable to have an implementation. Rather, as #devianfan alluded to in his comment, your single inheritance alternative fails to model the conceptual taxonomy.
It is about cross axial classifications. A window is both skinabble and draggable but neither of these qualities are codependent.
Consider that, as suggested by your example domain, your application code consists of a collection of graphical user interface elements. You might want to perform perform operations on subgroups of them based on their capabilities. For example you might manipulate the appearance of all skinnable elements based on some customization. On the other hand, there are probably elements of your GUI which are draggable and should be notified on certain user input events. A window is a good example of something which falls into both categories.
I would probably go like this
class Window
class Draggable : public virtual Window
class Skinnable : public virtual Window
class DraggableSkinnableWindow : Draggable, Skinnable
And provide default implementation in the pure virtual methods contained in Draggabel and Skinnable separately
class Draggable : public virtual Window {
virtual void aMethod() = 0;
void aMethodDefaultImplementation() = { //...// };
}
then inside DraggableSkinnable you have two options:
virtual void aMethod() = { aMethodDefaultImplementation() };
or
virtual void aMethod() = {// ...non-default implementation... //};
This has the benefit of providing a default implementation if you need one (as if aMethod was not pure virtual) but forcing you to ask for that explicitly (because it is purely virtual).
I think this is supposed to be a good example where MI makes sense.
It does, at long as Window, Draggable, Skinnable do not share common ancestor, at least other than pure abstract, otherwise you would need virtual inheritance.
Since it doesn't make sense to implement a class of Skinable, it should be defined abstract.
It can make sense, for example defining a property skin + setters and getters. You seem to be confusing abstract classes and pure abstract classes. Abstract classes have at least one pure virtual function, which means you cannot instantiate them. Pure abstract classes do not have any implementation of any method, they contain only pure virtual functions, and are often used as a realization interface concept in c++.
How would this look like if I would not use the concept of MI. Is the second example even a good solution for the same context but not using MI?
You cannot do it properly. c++ does not differentiate between classes and interfaces (as it does not provide such concept on language level). It is the same as stripping java or c# of interfaces. It would be possible if you provided all the compounds by hand i.e. Skinnable, Draggable bases, would produce SkinnableDraggable and/or DraggableSkinnable (which would probably be equivalent) dervided classes. This is quite a killer.
Your example, as others mentioned completely mixes unrelated concepts. E.g. Your Draggables and Skinnables must be Windowses. This is not obvious, and certainly not correct in general.

Using derived Class from CEdit in my DIalog

I'm doing an application using MFC. I just made a class that is derived from CEdit so I could intercept OnChar() and do data validation. How do I substitute the edit control in my application with the derived one I made?
Do NOT use GetDlgItem!!
GetDlgItem() returns a CWnd-pointer and nothing else. This means you have a sliced CMyCustomEdit pointer. Sure, it works in all cases where your method sends a message to the underlying HWND. But that's just pure luck! You can read more about the problem here.
The right solution is to subclass your edit control using DDX_Control.
I found the solution. The reason why I was having such a hard time is because I didn't use the Class Wizard to create the new class, making things very complicated. If you simply use the Class Wizard, you have the option to add control variables to your derived classes like if they were regular classes, as long as the base class is the right class for your element. This is not necessary though. All you have to do is create a pointer of the type of your derived class and cast the item you are trying to get, like you would normally do with a non-derived class.
Example of accessing an Edit Control using a class derived from CEdit
CMyCustomEdit * editPtr = (CMyCustomEdit*)GetDlgItem(IDC_EDIT1);
As mentioned below by another member (Thanks for that), using GetDlgItem is not a good idea. I actually, in my code, ended up Sub-Classing it so I could use my new class with my Edit Controls that already existed. As mentioned before, I did not understand that an Edit Control was not necessarily attached to CEdit, so the example above should give a clear idea that your IDC_EDIT can be used as CMyCustomEdit as well as a CWnd and so on; it will behave naturally as long as you reference it with the right classes.
Now for the Sub-Classing. If you actually want to make you Edit Control to always call your derived class before your base class, you will have to make it a Sub Class. Don't think of it as an Object Oriented concept, this is only so the messages (Like WN_CHAR) will go through your derived class first and then call the base class.
Example of Sub-Classing CMyCustomEdit on an Edit Control:
First you need to include the .h file of your new class in the .cpp and .h of your dialog box. Those are the ones that usually has the same name as your project. Here it will be MyMainDialog.
#include "CMyCustomEdit.h"
In the derived dialog class include a variable of the type of your new derived class:
class MyMainDialog : public CDialogEx
{
protected:
CMyCustomEdit m_cmCEdit;
}
Then in the OnInitDialog() of your derived dialog class (MyMainDialog) Sub-Class your edit control. For safety, add this after the regular code in the function and before the return (As usual):
m_cmCEdit.SubclassDlgItem(IDC_EDIT1, this);
After this is done, when you do anything in your Edit Control with the ID IDC_EDIT1, the messages will go trough CMyCustomEdit before going to CEdit. This usually is necessary when you need to overwrite messages from the base classes.
Hope it helps anyone with a similar question.

Should downcasting be avoided while using a class hierarchy in C++?

Let's say I'm writing an application which works with projects, and exposes different functionality depending on the type of the project. I have a hierarchy of classes for the different types of projects:
class AbstractProject
{
};
class ProjectA : public AbstractProject
{
};
class ProjectB : public AbstractProject
{
};
class ProjectC : public AbstractProject
{
};
Now, I was planning to have an AbstractProject *_currentProject pointer as a member in the application's main class, pop up a dialog box on startup and based on the selection, do:
_currentProject = new ProjectB(); // e.g.
Later, I'll have to downcast the pointer to the specific type to utilize the functionality specific to different Project-s. Somehow this makes me feel uneasy. Is there a Better Way of doing this?
Better way is to define pure virtual methods in base class and later implement all specific functionality in overloads in derived classes. Then call that method.
Yes you should use virtual methods instead, whenever possible.
The Command and the Visitor pattern may both apply here. You should decide for yourself which fits better for your case.
http://en.wikipedia.org/wiki/Command_pattern
http://en.wikipedia.org/wiki/Visitor_pattern
In pure OO, you should have virtual methods like everyone suggested. However, if you still need to go for specific member functions, try using one of the design pattern, may be command or visitor or even decorator...

Restrict method access to a specific class in C++

I have two closely related classes which I'll call Widget and Sprocket. Sprocket has a set of methods which I want to be callable from Widget but not from any other class. I also don't want to just declare Widget a friend of Spocket because that would give Widget access to ALL protected and private members. I want to restrict Widget's access to only a specific set of methods.
One solution I came up with is to create a nested class inside Sprocket that contains wrappers for these methods and make Widget a friend of this nested class. For example:
class Sprocket
{
public:
class WidgetInterface
{
friend class Widget;
WidgetInterface(Sprocket* parent) : mParent(parent) {}
private:
void A() { mParent->A(); }
void B() { mParent->B(); }
Sprocket* mParent;
};
private:
void A() { ... }
void B() { ... }
};
class Widget
{
public:
Widget(Sprocket* sprock) : mSprocketIface(sprock) {}
void doStuff() { mSprocketIface.A(); } // Widget can call Sprocket::A()
private:
Sprocket::WidgetInterface mSprocketIface;
};
This results in some code duplication because the method signatures are now declared in two places, but it works. But now suppose I want to add a subclass of Widget called SpecialWidget and I want that class to also have access to the Sprocket methods. I can simply add this new class to the Sprocket friends list or I can add yet another set of protected wrappers in Widget that SpecialWidget (and any other subclass) can access but you can see that this is now becoming a maintenance issue. I don't want to have to update the friends list or the wrappers if I add new classes or change the method signature. If I use the "add another set of wrappers" approach, the method signatures will be duplicated in three places!
Does anyone know of a simpler, cleaner way to do this?
If you have two tightly coupled classes, then it's really not worth trying to make friend access any more granular than it is. You control the implementation of both, and you should trust yourself enough to not abuse the ability to call some methods that you don't, strictly speaking, need to call.
If you want to make it clear for future code maintainers, add a comment to the friend declaration explaining why it is there (a good idea in general), and what private methods are allowed to be called by the friend class.
Sprocket has a set of methods which I want to be callable from Widget but not from any other class.
Why not save yourself some trouble & implement this set of methods in Widget, perhaps adding a Sprocket parameter to these methods?
I would have implemented WidgetInterface as a real interface inherited by Sprocket, so A and B are all that Widget know about. Okay, other can use that interface too, but they probably will have a reason for this.
The secret is all this access control is pointless and illusionary, and there's no way to really limit any access to anything. You are just complicating things and making it difficult to figure out what parts of widget are ok to use and what parts are not. Instead, make the interface for widget and sprocket more obvious, and perhaps have widget own a private sprocket. If people are so clueless that they will violate this there's no help for it, but if you make something abominable and hard to figure out it guarantees even people who know C++ well will be unable to easily make use of it.