Why are my overloaded functions not seen by a subclass - c++

I have a base class Base which provides a series of load functions, which read saved settings from a file. For example
void Base::load(QWidget *w);
virtual void Base::load(QTableWidget *t); // note this is declared virtual
void Base::load(QLineEdit *le);
Where Base::load(QWidget *w) will typically be called by a subclass on a high level widget. That routine will find the child widgets of the input widget (by type), and call the appropriate load routine on those. The overloading works as expected.
So in a subclass OkSubClass, I typically do a load like this:
void OkSubClass::load(void)
{
load(myMainWidget);
load(myOtherHighLevelWidget);
}
All is good - anything that is a child of either widget gets loaded.
Now I have a subclass of Base which needs to load things for a table slightly differently. It declares
virtual void ProblemSubClass::load(QTableWidget *t) ;
I also have some widgets used by this class that inherit a form class; e.g.
class myWidget: public QWidget, public MyForm { ... };
and ProblemSubClass has a member variable
myWidget *_myMainWidget;
now in the routine ProblemSubClass::load(void), I try to do the following:
ProblemSubClass::load(void)
{
load(_myMainWidget);
}
it complains that it can't convert _myMainWidget to a QTableWidget . Which surprises me, because I thought that ProblemSubClass should be able to see the load(QWidget) member function.
If I directly call the base class function, it works.
ProblemSubClass::load(void)
{
Base::load(_myMainWidget);
}
But I don't understand why it doesn't if I don't. Please enlighten me!

Unless you write using Base::load; somewhere in the declaration of the child class, that child class will not be able to see the other load functions declared in the base class.
It's one of those parts of C++ that appears odd at first.

Related

How does C++ knows child class calls a parent method?

I don't know how to summarize my question so couldn't find an answer on Google.
When overriding a parent method,
void Child::method(){
//stuff
Parent::method();
}
Works perfectly. But the parent method requires the information from the Child class instance to work properly, which is not given as arguments. So my question is, does C++ have a mechanism to let the Parent know which instance of a Child class calls a Parent method, like without doing Parent::method(this) ?
The thing that makes me think this is, if you do something like this,
int main(){
SomeParentClass::someMethod();
}
It gives: error: call to non-static member function without an object argument. So the compiler needs to know the instance, which was not also given in the child class. But did not raise an error so it must have known the instance.
Edit: I added the Qt tag because I am experimenting on a Qt class. So that I can give an example if needed.
Edit2:
devicedialog.h
class DeviceDialog : public QDialog
{
Q_OBJECT
public:
explicit DeviceDialog(QWidget *parent = nullptr);
int exec() override;
~DeviceDialog() override;
}
devicedialog.cpp
int DeviceDialog::exec(){
// My code.
return QDialog::exec();
}
exec() function activates and shows a QDialog on the screen. However, that way it is called, it seems like the parent method has no way of knowing which dialog to show (no parameters passed). The only knowledge could be the identity of the instance calling it. I am just asking if this knowledge transferred to the method in the background.
I think you are just being confused by the language's attempt to make things easier on you. Your example function is equivalent to
void Child::method(){
//stuff
this->Parent::method();
}
Just as you cannot call a (non-static) method in the child class without an object, you cannot call the parent's method without an object. However, the context is the body of such a method. Within the body, the context is assumed to be *this. Just as you can refer to data members without explicitly prefixing "this->", you can call methods without the prefix.
This is nothing special to member functions of a parent class. Calling a function of the child class via explicitly naming the type:
Child::method();
works in exactly the same way in this regard. Used outside of a member functions definition it causes the same error.
The relevant paragraph of the standard is ยง9.3.1:
When an id-expression that is not part of a class member access syntax
and not used to form a pointer to member is used in a member of class
X in a context where this can be used, if name lookup resolves the
name in the id-expression to a non-static non-type member of some
class C, and if either the id-expression is potentially evaluated or C
is X or a base class of X, the id-expression is transformed into a
class member access expression using (*this) as the postfix-expression
to the left of the . operator.
So, in other words, the call
Parent::method();
inside a member function is transformed into something akin to
(*this).Parent::method();
This is still a c++ specific question. Qt just utilizes it. You need to study objects, inheritance, and virtual methods.
void Child::method() {
Parent::method();
// this->Parent::method();
}
The above works because the child has access to the parents methods (that are not private). Because the method is an override of the parents virtual method, the only way for the compiler to know you want to call the parents method is to call it with scope resolution '::' in the child.
int main() {
SomeParentClass::someMethod();
}
The above does not work because there is no instantiated object. When you call a method, you call it on the object (unless it is a static method). So instead you would do something like:
int main() {
SomeParentClass parent;
parent.someMethod();
ChildClass child;
child.someMethod(); // accesses the childs overridden method and not the parents.
}

Is it possible to have a base class method that calls the same (but overridden method) of all it's derived classes?

It's a bit hard to explain in words, so I'll give an example:
(The following code might have incorrect syntax but it suffices to give an idea)
class A
{
public:
static void Update(UINT someValue);
};
class B : public A
{
public:
static void Update(UINT someValue);
};
class C : public A
{
public:
static void Update(UINT someValue);
};
I know static members function do not override each other,
but let's suppose they do.
What I want to achieve, is when A::Update(someValue); is called,
It should implicitly call B::Update(someValue), and also C::Update(someValue), as well as call every static void Update(UINT someValue) method of other classes derived from A
Is this possible in one way or another?
And if it is, how would you do it?
I think you should be using composite pattern instead. You can read about it at http://en.wikipedia.org/wiki/Composite_pattern and http://www.javacamp.org/designPattern/composite.html
That info below my comment is not enough to have a clear idea about your code but I was thinking if it is possible to do something similar to what C# does with events, where you can register events and the class that triggers then (your base class in that case) can implement a list of function pointers (pointing to the derived methods, which in that case you have to have instances of the derived classes) and call all of then iterating this list. Just an idea, don't know if this is what you need.
There's no way to do it automatically. A simple way to get the effect is for each derived class to call the function of its base class:
class A
{
public:
static void Update(UINT someValue) {
std::cout << "A\n";
}
};
class B : public A
{
public:
static void Update(UINT someValue) {
A::Update(someValue);
std::cout << "B\n";
}
};
If you prefer to work from bottom to top, you could have each class do its work before calling the derived class. Of course there's nothing to stop a derived class from implementing Update and not calling its base class. It is however fine for a class to not implement Update at all -- it doesn't care about updates, but its base class's function can still be called. So it's not a huge burden on implementers, they just have to follow the rule that if they implement the function, they have to call the base.
Another way might be for the base class to keep a list of "listeners" who are interested in updates, and to call them in turn whenever an update occurs. Each derived class can then register a suitable listener.
It might be difficult to make code like this exception-safe, though, if each level makes changes but one or more levels may throw.

Writing polymorphic class data to a file?

So I have these classes. There's one base class, but it has/will have lots and lots of derivatives, and those derivative classes will be able to have derivatives as well. I'd like to be able to have a function that writes their binary data to a file, but I'm not sure how to do this with lots and lots of derived classes.
I was thinking something along the lines of:
void writeData(ofstream & _fstream)
{
_fstream.write()//etc..
}
But then each derived class that implemented this method would have to write all of it's parent class's data, and that would be duplicating a lot of code.
What's the best way to do this without rewriting all of the previously written writeData() code?
You can call the base class implementation from the derived class implementation:
void Derived::writeData(ofstream & _fstream)
{
// Base class writes its data
Base::writeData(_fstream);
// now I can write the data that is specific to this Derived class
_fstream.write()//etc..
}
Derived class can call base write methods to avoid code duplication. In fact, that may be the only way to go if some parent's data is private but still is indirectly used.
If you want to avoid re-engineering all the derived class' implementation of the serialization functions, you can go in the other direction, from the base to the derived classes:
In your base class provide a non-virtual function to start the serialization process. Client code calls this function via a pointer (or reference). Also provide a virtual function that does the serialization for the subclass. Call that function from the base class' Serialize function.
(EDIT) If you want to provide default functionality for serializing the subclasses, but still want to be able to provide specialized functionality for specific cases, then the function that serializes the subclasses need not be pure virtual. However, by my reading of your OP it seemed to me that every subclass would need to be required to provide this functionality. To model that requirement, I have made the DoSerialize function pure virtual here.
Example:
class Base
{
public:
void Serialize() const;
virtual void DoSerialize() = 0;
};
class Derived : public Base
{
public:
void DoSerialize() { /* MAGIC HAPPENS */ };
};
void Base::Serialize() const
{
/* .. do serialization of base class here, or at the end -- whichever is appropriate .. */
this->DoSerialize(); // serialize the derived class
}
/* ... */
Base* GetObject()
{
/* ... */
}
int main()
{
Base* obj = GetObject();
obj->Serialize();
}
Ultimately, it is the responsibility of each derived class to make sure that it has been serialized properly. A derived class may need to serialize some data before or after the base class, depending on its purpose. It may also want to totally override the way the base class data is serialized.
Look at it this way - the function being performed here is serialization and de-serialization. The critical thing here is that it needs to be performed correctly. Therefore, the only class that is in a good position to do this is the one with complete knowledge. In other words, its your derived class.
So, there are times when you will have to call Base::writeData(), but whether or not you do that should be left totally up to the derived class. Remember, what you want is for your class hierarchy to satisfy some basic design principles. Once you've got that, it should be relatively easy.

A cleaner code alternative to polymorphism

Building a GUI system and I have a few classes for different GUI components that derive from a base "GUIcontrol" class. What I want is to have just one function to return any type of component but be able to work with the functions specific to that component type (functions of the derived class). I noticed that the polymorphism approach is going to become a problem I have to declare all the derived functions in the base which is unnecessary for this, since I will never create an object just from the base class.
class GUIcontrol {
protected:
std::string _name;
// these two methods (along with name()) will be used by all types
virtual void position(/*parameters*/)
virtual void useImage(/*parameters*/)
// these should be only in derived types
virtual void setHotSpot(/*parameters*/);
virtual void setScrollButtons(/*parameters*/);
public:
std::string name();
/*etc*/
}
class GUIbutton : public GUIcontrol {
public:
void setHotSpot(/*parameters*/);
}
class GUIscrollBar : public GUIcontrol {
public:
void setScrollButtons(/*parameters*/);
}
GUIcontrol* GUIsystem::getControl(std::string name);
The problem with this is that if I want to add more functions unique to GUIbutton or GUIscrollBar, or any functions to other derived GUI classes, I also have to declare them virtual in the base class so the compiler doesn't complain about something like "setHotSpot" not being a member of the base class it returns.
The base class does have member functions that will apply to all the derived classes, such as telling the object where it should be positioned, what image it needs to use, what it should be called, etc. But I don't want to keep stuffing the base class with other functions that need to stay exclusive to certain derived classes.
As I keep adding more virtual functions I would end up with a huge blob object for the base class. Can I design this in a cleaner way? Note that I am still not sure if I want to use static_cast/dynamic_cast for getControl() to solve this but just want to know if there are any other ways around this to clean it up.
The base class should only contain methods for functionality common to all controls.
If you're going to use functionality that only makes sense for one type of control, you should be checking that the control is of the correct type anyway, and can then cast it to that type.
The base class is exclusively common functionality. If you want your method to behave differently for different controls, use dynamic_cast. If you want it to act the same for all controls, use a virtual method.
This is your problem:
What I want is to have just one
function to return any type of
component but be able to work with the
functions specific to that component
type (functions of the derived class).
What you want is to treat them the same but differently. Huh. I wonder how you're going to make that work. You need to decide if you want to treat them all the same, or if you want to treat them differently.
Type checking and then downcasting isn't the right way to do this. What you should be doing is placing generic methods onto your base class which perform the types of operations you want, and then overriding them in subclasses. For example, if you want the GUIControl to be able to draw itself, then put a doDraw() method on the base class, then override that in each subclass to do as is needed. If you instead put a getTitleBar(), getText() etc. methods on your subclass, then have the caller downcast and calls those specific methods depending on the type, your encapsulation is broken. If you have some common code that multiple subclasses need to do their drawing, then you factor this out either through another parent class, or through composition. Using dynamic_cast, or putting specific methods on the generic subclass, will likely make your code worse.
If I have this right: You want to be able to pass around base class objects but have a clean way to call specific derived class methods where the derived class implements those methods?
Sounds like the 'mixin' pattern might help:
struct Base
{
virtual ~Base() {}
};
struct Mixin
{
virtual ~Mixin() {}
virtual void mixedMethod() = 0;
};
struct Concrete : Base, Mixin
{
virtual void mixedMethod() { std::cout << "Mixing" << std:: endl; }
};
Base* create() { return new Concrete;}
bool mixIt(Base& b)
{
Mixin* m = dynamic_cast<Mixin*>(&b);
if (m)
m->mixedMethod();
return m;
}
void test ()
{
Base* b = create();
assert(mixIt(*b));
Base base;
assert(!mixIt(base));
}
[ Yes, real code never uses struct for polymorhic classes; just keeping it compact.]
The idea here is that the availability of a given method is encapsulated in the Mixin class, which is an pure abstract base class, possibly with only a single pure virtual function.
If you want "know" your base class object is of the derived type, you can call the mixin classes method. You can wrap the test and the call in a non-member function; this allows you to keep the base calss interface itself clean.

Polymorphism and checking if an object has a certain member method

I'm developing a GUI library with a friend and we faced the problem of how to determine whether a certain element should be clickable or not (Or movable, or etc.).
We decided to just check if a function exists for a specific object, all gui elements are stored in a vector with pointers to the base class.
So for example if I have
class Base {};
class Derived : public Base
{
void example() {}
}
vector<Base*> objects;
How would I check if a member of objects has a function named example.
If this isn't possible than what would be a different way to implement optional behaviour like clicking and alike.
You could just have a virtual IsClickable() method in your base class:
class Widget {
public:
virtual bool IsClickable(void) { return false; }
};
class ClickableWidget : public Widget
{
public:
virtual bool IsClickable(void) { return true; }
}
class SometimesClickableWidget : public Widget
{
public:
virtual bool IsClickable(void);
// More complex logic punted to .cc file.
}
vector<Base*> objects;
This way, objects default to not being clickable. A clickable object either overrides IsClickable() or subclasses ClickableWidget instead of Widget. No fancy metaprogramming needed.
EDIT: To determine if something is clickable:
if(object->IsClickable()) {
// Hey, it's clickable!
}
The best way to do this is to use mixin multiple inheritance, a.k.a. interfaces.
class HasExample // note no superclass here!
{
virtual void example() = 0;
};
class Derived : public Base, public HasExample
{
void example()
{
printf("example!\n");
}
}
vector<Base*> objects;
objects.push_back(new Derived());
Base* p = objects[0];
HasExample* he = dynamic_cast<HasExample*>(p);
if (he)
he->example();
dynamic_class<>() does a test at runtime whether a given object implements HasExample, and returns either a HasExample* or NULL. However, if you find yourself using HasExample* it's usually a sign you need to rethink your design.
Beware! When using multiple inheritance like this, then (HasExample*)ptr != ptr. Casting a pointer to one of its parents might cause the value of the pointer to change. This is perfectly normal, and inside the method this will be what you expect, but it can cause problems if you're not aware of it.
Edit: Added example of dynamic_cast<>(), because the syntax is weird.
If you're willing to use RTTI . . .
Instead of checking class names, you should create Clickable, Movable, etc classes. Then you can use a dynamic_cast to see if the various elements implement the interface that you are interested in.
IBM has a brief example program illustrating dynamic_cast here.
I would create an interface, make the method(s) part of the interface, and then implement that Interface on any class that should have the functionality.
That would make the most sense when trying to determine if an Object implements some set of functionality (rather than checking for the method name):
class IMoveable
{
public:
virtual ~IMoveable() {}
virtual void Move() = 0;
};
class Base {};
class Derived : public Base, public IMoveable
{
public:
virtual void Move()
{
// Implementation
}
}
Now you're no longer checking for method names, but casting to the IMoveable type and calling Move().
I'm not sure it is easy or good to do this by reflection. I think a better way would be to have an interface (somethign like GUIElement) that has a isClickable function. Make your elements implement the interface, and then the ones that are clickable will return true in their implementation of the function. All others will of course return false. When you want to know if something's clickable, just call it's isClickable function. This way you can at runtime change elements from being clickable to non-clickable - if that makes sense in your context.