How can I resolve this redundancy caused by inheritance and nested class? - c++

I have 2 derived classes, in one of these classes I want to customize the implementation of a nested class that is in the base. In the other, I just want to use the base object.
I have encountered a problem that can be demonstrated with below example:
class Widget
{
public:
class Settings
{
// ...
}
// ...
protected:
Settings m_settings;
}
// -------------------------------------------------------
class LimitedWidget : public Widget
{
// ...
// the settings are the same, so using base m_settings object.
}
// -------------------------------------------------------
class SpecialWidget : public Widget
{
public:
class Settings : public Widget::Settings
{
// customize the settings for SpecialWidget
}
// ...
protected:
Settings m_settings; // now I must declare another m_settings object.
}
Uh oh, this is redundant. We already have m_settings defined in our base class Widget, but I don't want to use that in all derived classes (eg. SpecialWidget). I can't make m_settings private in the base class, because I want to use that object in LimitedWidget. But I don't want 2 settings objects, one of which is useless, in SpecialWidget.
Is there a solution?
Thank you for your time.

You could try something like this:
class Widget
{
...
protected:
Settings* m_settings;
public:
void initialize()
{
m_settings = createSettings();
}
protected:
virtual Settings* createSettings()
{
return new Settings();
}
...
} // class Widget
And then:
class SpecialWidget: public Widget
{
public:
class SpecialSettings: public Settings
{
// customize the settings for SpecialWidget
}
protected:
Settings* createSettings()
{
return new SpecialSettings();
}
} // class SpecialWidget
In other words, the base class creates the default settings within the initialize method and your special widget overrides this, creating the special settings.

Related

C++ How to reference an "unknown" Class

I would like to build a simple application framework. The user is supposed to create a class derived from a base class and either use the properties and methods of the base class or override them with his own. Unfortunately, it is not at all clear to me how to instantiate a user class object from my framework library.
// library base class in appframework.hpp
class BasicApp
{
public:
// Initialisation
int initApp();
// Update is called from main loop
int Update();
// Handle input
int KeyInput(u32 KeysDown, u32 KeysHeld, u32 KeysDownRepeat, u32 KeysUp);
};
// user code
#include <appframework.hpp>
class AppMain: public BasicApp
{
// Handle input
int KeyInput(u32 KeysDown, u32 KeysHeld, u32 KeysDownRepeat, u32 KeysUp)
{
if (KeysDown & KEY_A) return 1;
return 0;
}
};
But how will my framework know about the AppMain class? The user should be able to override existing properties and methods and add their own that they can use but that the framework ignores.
I imagine it to be similar to a Java/Kotlin app in Android Studio:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// do whatever you want here
}
}
Are there any similar concepts in C++?
Thank you!
Simply create BasicApp with virtual method and default implementation
class BasicApp {
public:
virtual void onCreate() {/*default*/ }
virtual void onStop() {/*default*/ }
};
Add AppMain that inherits from BasicApp and overrides BasicApp methods. In AppMain there is no override for onStop() that means it will be default.
class AppMain : public BasicApp {
public:
void onCreate() override {
BasicApp::onCreate();//optional to run default aka super in Kotlin
//add your override here
}
};
Unlike Kotlin not calling BasicApp::onCreate() in overriden onCreate will not throw.

access protected variable - complicated situation with inheritance and sub-classes

Hmm... I'm trying to break down my problem...
There is a library with some classes that do almost what I want. I can't change classes of the library so I want to derive them and change what I need.
In this case there is a derived class in the library with two subclasses. Now I derive the class and the subclasses.
In the second sub-class there is a virtual method witch modifies a protected variable from the first sub-class.
I want to override the virtual method with a new virtual method which calls the old virtual wethod an then modify the protected variable again.
Why am I getting the error in mySubClass2 while accessing fResponse?
How can I solve my problem?
class libraryClass : pulic someLibraryBaseClass {
protected:
libraryClass::librarySubClass2 lookUpFunction(int ID) {
//some magic to find the obj
return obj;
}
public:
class librarySubClass2;
class librarySubClass1 {
public:
librarySubClass1(libraryClass baseObj) {
myBaseObj = baseObj;
}
void someCallingFunction(int ID) {
libraryClass::librarySubClass2 obj = myBaseObj->lookUpFunction(ID)
obj->someHandleFunction(this)
cout << fResponse;
}
protected:
friend class librarySubClass2;
unsigned char fResponse[200];
private:
libraryClass myBaseObj;
};
class librarySubClass2 {
protected:
virtual void someHandleFunction(libraryClass::librarySubClass1* obj) {
snprintf((char*)obj->fResponse, sizeof obj->fResponse, "Some Text...\r\n"
}
};
};
class myDerivedClass : public libraryClass {
public:
class mySubClass2 : public libraryClass::librarySubClass2;
class mySubClass1 : public libraryClass::librarySubClass1 {
protected:
friend class mySubClass2;
};
class mySubClass2 : public libraryClass::librarySubClass2 {
protected:
virtual void someHandleFunction(libraryClass::librarySubClass1* obj) {
libraryClass:librarySubClass2::someHandleFuntion(obj);
snprintf((char*)obj->fResponse, sizeof obj->fResponse, "Add some more Text...\r\n"
}
};
};
Edit: Forgot * in Method of mySubClass2
Possible solution:
class mySubClass2 : public libraryClass::librarySubClass2 {
protected:
virtual void someHandleFunction(libraryClass::librarySubClass1* obj) {
libraryClass:librarySubClass2::someHandleFuntion(obj);
myDerivedClass::mySubClass1* nowMyObj = (myDerivedClass::mySubClass*) obj;
snprintf((char*)nowMyObj->fResponse, sizeof nowMyObj->fResponse, "Add some more Text...\r\n"
}
};
Now I derive the class and the subclasses.
In your example code, you're only deriving the main class and not the subclass. You have to inherit also the subclass:
class libraryClass : pulic someLibraryBaseClass
{
class librarySubClass1 : public someLibraryBaseClass::someLibrarySubClass1 { };
// ....
};
But that can be done only if the subclass is accessible (protected/public).
As far as I can tell you wonder why you can't access obj->fResponse in
void mySubClass2::someHandleFunction(libraryClass::librarySubClass1 obj) { ... }
Well, obj is of type librarySubClass1 which inherits its share of fResponse from the common ancestor. However, that is the share of a relative of mySubClass2, not yours as you are mySubClass2! You can only access the fResponse member of objects which are known to be of type mySubClass which actually happens to be known to be not the case for a librarySubClass1 object.
Getting access to librarySubClass::fResponse is as if you got free access to your uncle's inheritance from your grandparents. Unless you have a very unusual family sharing its wealth freely among all family members, you probably won't have access to your uncle's inheritance either.
Because fResponse in mySubClass2 is treated as protected and at that point it is outside of libraryClass, it only worked on librarySubClass2 because it is inside libraryClass.

Common base class in plug-in code

The application defines 3 interfaces to be implemented in a plug-in. Widget is always the base.
// Application code...
class Widget {
virtual void animate() = 0;
};
class BigWidget : public Widget {
};
class SmallWidget : public Widget {
};
Every interface implementation is derived from NiceWidget which provides some plug-in internal common information.
// Plug-in code...
class NiceWidget {
// nice::Thing is only known in plug-in code.
nice::Thing thing();
};
class NiceBigWidget : public NiceWidget, public BigWidget {
void animate() override;
};
class NiceSmallWidget : public NiceWidget, public SmallWidget {
void animate() override;
};
func is called from application code. wid is known to be implemented by this plugin. Thus wid is also a NiceWidget. The goal of func is to call the thing method of it.
// Plugin-in code...
void func(Widget* wid) {
// wid is either NiceBigWidget or NiceSmallWidget.
auto castedBig = dynamic_cast<NiceBigWidget*>(wid);
if (castedBig) {
castedBig->thing().foo();
return;
}
auto castedSmall = dynamic_cast<NiceSmallWidget*>(wid);
if (castedSmall) {
castedSmall->thing().foo();
return;
}
assert(false);
}
But trying to cast wid to every Nice* can become very awful with increasing hierarchy size. Are there better solutions out there?
First: if you know that wid will always be a NiceWidget*, why not say so in func()? And you would not need a cast at all:
void func(NiceWidget* wid)
{
wid->thing().foo(); // Done
}
Even if you can't change the function signature for whatever reason, you would only need one cast:
void func(Widget* wid)
{
NiceWidget* casted = dynamic_cast<NiceWidget*>(wid);
if (casted)
casted->thing().foo();
else
throw std::exception(); // Well, throw the right exception
}
You can assert() instead of throwing an exception, of course, if you think it is better for your purposes.
In any case, you just need a pointer to the class that defines the functions you need to use (in this case, thing()), not to the most derived classes. If you will override the function in derived classes, make it virtual and you are done anyway.
If you know, that every NiceWidget is Widget, you should consider extending NiceWidget from Widget.
class Widget {
virtual void animate() = 0;
};
class BigWidget : public Widget {
};
class SmallWidget : public Widget {
};
class NiceWidget : Widget{
// nice::Thing is only known in plug-in code.
nice::Thing thing();
};
class NiceBigWidget : public NiceWidget, public BigWidget {
void animate() override;
};
class NiceSmallWidget : public NiceWidget, public SmallWidget {
void animate() override;
};
There will be another problem called The diamond problem, and it may be solved using virtual extending
After that it's should be OK to dynamic_cast from Widget to NiceWidget

How to use shared_ptr in a member which is not a shared_ptr?

I'm working on a couple of classes and I'm wondering how I can use a normal member in my application class, where the member needs to use shared_from_this()?
Here is some code to clarify what I mean (see comments)
class Observable {
public:
void addObserver(boost::shared_ptr<Observer> observer) {
// add to a list
}
};
class Observer {
public:
virtual void onUpdate() = 0;
};
class MyObservableType : public Observable {
};
class ApplicationModel : public Observer {
private:
MyObservableType mot;
public:
void setup() {
// how do I pass this as a boost::shared_ptr, as ApplicationModel is not
// a boost::shared_ptr in the Application class this using a call to
// "shared_from_this()" (and inheriting public shared_from_this<ApplicationModel>
mot.addObserver([shared_from_this])
}
};
class Application {
private:
ApplicationModel model;
public:
void setup() {
model.
}
};
You have three solutions to this problem:
First solution: force the application to create a shared_ptr by making its constructor private. This is what I would recommend to do for any class that derivates from enable_shared_from_this
class ApplicationModel : public Observer, public boost::enable_shared_from_this<ApplicationModel> {
private:
ApplicationModel(); // private constructor
MyObservableType mot;
public:
// an instance of this class can only be created using this function
static boost::shared_ptr<ApplicationModel> buildApplicationModel() {
return boost::make_shared<ApplicationModel>();
}
void setup() {
mot.addObserver(shared_from_this()) ;
}
};
Second solution: change your code design.
You should not ask the ApplicationModel to register itself to the Observable, but do it yourself. This way the ApplicationModel doesn't enforce anything, but if its owner wants to call addObservable, it has to create a shared_ptr. This is more or less what is called dependency injection.
class Application {
private:
boost::shared_ptr<ApplicationModel> model;
MyObservableType mot;
public:
void setup() {
model = boost::make_shared<ApplicationModel>();
mot.addObserver(model);
}
};
EDIT: Third solution: use a dummy shared_ptr, like this:
class ApplicationModel : public Observer {
private:
boost::shared_ptr<ApplicationModel> myself;
MyObservableType mot;
public:
void setup() {
mot.addObserver(myself) ;
}
ApplicationModel() {
myself = boost::shared_ptr<ApplicationModel>(this, [](ApplicationModel*) {});
}
~ApplicationModel() {
mot.removeObserver(myself);
assert(myself.unique());
}
};
The idea is to create a shared_ptr to this and to tell shared_ptr not to call the destructor (here I use an empty lambda function but you can easily create an inline structure). This is a hack and you shouldn't do so.
You can't. shared_from_this() requires that your object be allocated dynamically via a shared_ptr.
See this page of the documentation, which states:
Requires: enable_shared_from_this must be an accessible base class of T. *this must be a subobject of an instance t of type T . There must exist at least one shared_ptr instance p that owns t.
So you would need to alter your code to have any instances of ApplicationModel be "owned" by a shared_ptr. For example:
class ApplicationModel :
public Observer,
public boost::enable_shared_from_this<ApplicationModel>
{
//...
void setup() {
mot.addObserver(shared_from_this());
}
};
class Application {
private:
// Application object must initialize this somewhere
boost::shared_ptr<ApplicationModel> model;
//...
};

How to declare factory-like method in base class?

I'm looking for solution of C++ class design problem. What I'm trying to achieve is having static method method in base class, which would return instances of objects of descendant types. The point is, some of them should be singletons. I'm writing it in VCL so there is possibility of using __properties, but I'd prefer pure C++ solutions.
class Base {
private:
static Base *Instance;
public:
static Base *New(void);
virtual bool isSingleton(void) = 0;
}
Base::Instance = NULL;
class First : public Base { // singleton descendant
public:
bool isSingleton(void) { return true; }
}
class Second : public Base { // normal descendant
public:
bool isSingleton(void) { return false; }
}
Base *Base::New(void) {
if (isSingleton())
if (Instance != NULL)
return Instance = new /* descendant constructor */;
else
return Instance;
else
return new /* descendant constructor */;
}
Arising problems:
how to declare static variable Instance, so it would be static in descendant classes
how to call descendant constructors in base class
I reckon it might be impossible to overcome these problems the way I planned it. If so, I'd like some advice on how to solve it in any other way.
Edit: some minor changes in code. I have missed few pointer marks in it.
Just to check we have our terminologies in synch - in my book, a factory class is a class instances of which can create instances of some other class or classes. The choice of which type of instance to create is based on the inputs the factory receives, or at least on something it can inspect. Heres's a very simple factory:
class A { ~virtual A() {} };
class B : public A {};
class C : public A {};
class AFactory {
public:
A * Make( char c ) {
if ( c == 'B' ) {
return new B;
}
else if ( c == 'C' ) {
return new C;
}
else {
throw "bad type";
}
}
};
If I were you I would start again, bearing this example and the following in mind:
factorioes do not have to be singletons
factories do not have to be static members
factories do not have to be members of the base class for the hierarchies they create
factory methods normally return a dynamically created object
factory methods normally return a pointer
factory methods need a way of deciding which class to create an instance of
I don't see why your factory needs reflection, which C++ does not in any case support in a meaningful way.
Basing this on the answer by #Shakedown, I'll make Base be templated on the actual type, using the CRTP:
template <class T>
class Base
{
public:
static std::auto_ptr<Base<T> > construct()
{
return new T();
}
};
class First : public Base<First>
{
};
class Second : public Base<Second>
{
};
This is nice because construct is now once again a static member. You would call it like:
std::auto_ptr<First> first(First::construct());
std::auto_ptr<Second> second(Second::construct());
// do something with first and second...
You can create a Singleton class and a NonSingleton class, and make all the descendants inherit one of them.
class Base {
public:
static Base *New() = 0;
}
class SingletonDescendant: public Base {
public:
*Base::New() {
if (Instance != NULL)
return Instance = new /* descendant constructor */;
else
return Instance;
}
private:
static Base *Instance;
}
SingletonDescendant::Instance = NULL;
class NonSingletonDescendant: public Base {
public:
*Base::New() {
return new;
}
}
class First : public SingletonDescendant{ // singleton descendant
}
class Second : public NonSingletonDescendant{ // normal descendant
}
It solves the issues that you raised:
How to declare static variable Instance, so it would be static in descendant classes: It exists only in the SingletonDescendant class.
How to call descendant constructors in base class: Using the New function
I have to write construct() method in every descendant; I consider it redundant, as it is obvious what it has to do: Now it is only in SingletonDescendant and NonSingletonDescendant.
How about something like this:
class Base
{
public:
virtual Base construct() = 0;
};
class First : public Base
{
public:
Base construct(){ return First(); // or whatever constructor }
};
class Second : public Base
{
public:
Base construct(){ return Second(...); // constructor }
};