Simple inheritance problem in C++ - c++

I am trying to understand inheritance in C++ properly.
Firstly, is it ok to have a class that returns instantiations of itself?
class Class1 {
public:
Class1 foo();
}
Basically, I have a class that derives equations so it takes an equation and returns an equation.
If I wanted some subclasses of Class1 that also return instantiations of themselves:
class Child : public Class1 {
public:
Child bar();
}
and I wanted to use some of the functions of Class1 but instead of returning Class1's, I would want to return Child objects, would this be possible with inheritance?
Thank you, hopefully this question isn't too dumb.

As written, there's no problem, but how do you intend to use it. Return
by value involves copy, and copy and polymorphism don't generally go
well together. Usually (but there are exceptions), it's preferable to
return a pointer to a newly allocated instance. (You'll have to address
memory management issues if you do this. If the logical meaning of the
class is such that cycles are impossible, then you can use
std::shared_ptr; otherwise, you'll have to do something else.)

Yes,
It looks to me like you are described a well defined problem, known in Desing Pattern parlance, as a Factory.
Consider the following:
class Class1 {
public:
static Class1 * getInstance( Equation * eq );
virtual void foo() = 0;
}
class Child : public Class1 {
public:
virtual void foo();
}
class OtherChild : public Class1 {
public:
virtual void foo();
}
You would implement the foo() method differently for both children.
So, for example, you could:
int main(){
Equation myEquation("x=y/4");
Class1 * myInstance = Class1::getInstance ( &myEquation );
myInstance->foo(); //would call the virtual method of the child class. You don't care what subclass, this was figured out by the "getInstance" method.
}

Firstly, is it ok to have a class that
returns instantiations of itself?
Yes, it's OK, and in your case it sounds like a fine design. You can have the design that your proposed, or you can have a different design where your class will return a different object, e.g. class DerivedEquation, or you can also have a class Deriver which will take an Equation and return anEquation. All these designs are fine.
If I wanted some subclasses of Class1
that also return instantiations of
themselves and I wanted to use some of
the functions of Class1 but instead of
returning Class1's, I would want to
return Child objects, would this be
possible with inheritance?
That's fine too. You can haveClass1::foo() and Child::bar() just as you proposed. Also, if you don't want to have 2 different function names, you can change the definition of foo to Class1 * foo() or Class1 & foo(), and then you will be able to overload it in Child.

Related

How to use functions from derived class without adding them to the base class

This is very likely a silly question, but I can't seem to figure out if this is at all possible and if it should actually be done.
Say some code relies a lot on using a certain virtual base class acting as an interface and then deriving several subclasses that implements the virtual methods the base class. Is it possible to use functionality not exsisting in the base class (interface) below without completely disregarding the solid principles, when the rest of the program must not see anything but the base class "interface"? Like in the example below, is it possible to use bar() from the B class inside the function that only knows of A? And should I just add bar() to the "interface" instead?
// Base class - "interface"
Class A
{
public:
virtual int foo();
}
// Derived class - implementing the "interface" + more
Class B: public A
{
public:
int foo();
int bar();
}
int main()
{
function(A); // Some magic function that would utlize the bar() method
return 0;
}
The short answer is yes, use the dynamic_cast operator (but see below). The magic function would look something like this:
void function(A& a)
{
B* b = dynamic_cast<B*>(&a);
if (b)
{
// Object is a B...
b->bar();
}
else
{
// fallback logic using only methods on A
}
}
But be aware that many programmers consider this a code smell. In particular, if there's no way to implement the "fallback" branch, then it suggests the function should really accept a B and something in the design may be amiss. (It's hard to say when talking in such generalities, however.) Also be aware that dynamic_cast can be expensive, particularly with complex class hierarchies.
If at all reasonable, it's preferable to move the B-specific logic into the B class somehow. You might also consider making the bar method a member of the A class (A would provide some sensible default implementation). Another approach might be to create a new interface to hold the bar method and have your function accept an object of that type. (The B class would implement both A and the new interface.)

Runtime introspection in C++

I have a class that looks like this:
class MyClass {
public:
void doSomething() { // nothing here };
}
and it also has a subclass that looks like this
class MyChildClass : MyClass {
public:
void doSomething() { // actual code here };
}
As you can see the doSomething() function does nothing in the parent class, but the child class overwrites it and adds actual code. My problem is that I am attempting to do something like this:
MyClass foo = MyChildClass();
foo.doSomething();
I was quite shocked to find that in this case, MyClass, and not MyChildClass's version of doSomething() is called, even though foo is actually of type MyChildClass. I have far more experience in Objective-C than C++ so this is very strange for me. It seems that C++ is determining which version of doSomething() needs to be called at compile-time, rather than inspecting the type of the object at run-time and calling the correct version.
This is problematic for me, because in my actual code what I have is one parent class and multiple different child classes that inherit from it. Each of these child classes overwrites the doSomething() function with their own unique implementation. I end up having an std::vector full of MyClass objects (which is really full of many different types of objects that each inherit from MyClass) and I want to loop through each of these object and invoke their version of doSomething() without actually knowing their type at compile-time. This would be easy in Objective-C, but is there any way for me to accomplish this in C++?
You need two things:
A reference or pointer to the created object, so that it isn't copy-sliced.
Having the member function virtual in the base class.
E.g., off the cuff,
struct MyClass{ virtual void foo() {} };
struct Derived: MyClass { void foo() override { /* ... */ } };
auto main() -> int
{
MyClass&& o = Derived{};
o.foo();
}
But why not just use the Derived type for the declaration?
” I end up having an std::vector full of MyClass objects (which is really full of many different types of objects that each inherit from MyClass) and I want to loop through each of these object and invoke their version of doSomething() without actually knowing their type at compile-time.
A vector<MyClass> slices each item to just the MyClass part. You can use a vector of pointers. If these are owning pointers, use a smart pointer like shared_ptr or unique_ptr.
If you want to run function based on run time information, you need to declare function as virtual function.

Call a function of an object referenced by a void Pointer

I have a function like this:
void something(void *obj)
{
obj->Set();
}
The compiler says that left of the dereference operator has to be a pointer to a class/struct/union/generic (translated from german not sure about wording).
The idea is that I want to call the something function of obj no matter what is passed to something. It is ensured that it has this function. How can i achieve that?
--EDIT--
I started to work on an existing Software which has like > 100 Classes for datatypes. In one part of the code there is a big switch statement which depending on an id creates an instance of one of these classes and calls the Set function for that one. Now i want to do multiple of these calls parallel, and because of this i want to bring the ->Set() call to a seperate function which i then can call in a new thread. Sadly there is no baseclass and i cant change too much in the "big picture". What is the best way to do this?
C++ doesn’t allow this (for good reasons: even if you can ensure that the object always has a function, C++ cannot, and since you can make mistakes, C++ is justified in distrusting you).
The proper way to do this is to have a common base class which defined this method for all types that you want to use here, and then use this common base class as the argument of this function.
Alternatively, if it’s known at compile time which type is used here, then the appropriate implementation uses templates:
template <typename T>
void f(T const& obj) {
obj.something();
}
Whatever you do, void* is not appropriate. There are very rare legitimate use-cases for it in C++.
You need a base class or interface for whatever is passed into doSth:
class Base
{
public:
virtual void something() = 0; //override this in derived classes
}
doSth(Base* obj)
{
obj->something();
}
You can also cast the void* back to the original type:
doSth(void* obj)
{
((Base*)obj)->something();
}
but passing a void* as parameter suggests a faulty design. What exactly are you trying to achieve?
You need to implement pure virtual Base class with this function:
class Base
{
public:
virtual ~Base(){}
virtual void somefunction()=0;
}
class Derived1: public Base
{
public:
void somefunction()
{
//do something
}
}
class Derived2: public Base
{
public:
void somefunction()
{
//do something
}
}
And than use dynmic cast to get Base* from void*
doSth(void *obj)
{
Base *bobj=dynamic_cast<Base*>(obj);
if ( bobj )
bobj->somefunction();
}
Or mor simplier:
doSth(Base *obj)
{
obj->somefunction();
}
And usage is like:
Base *p1 = new Derived1();
Base *p2 = new Derived2();
doSth(p1); // cals somefunction in Derived1 class
doSth(p2); // cals somefunction in Derived2 class
The doSth method could take a function pointer as a parameter.
doSth( (*someFunc)() ) {
obj->*someFunc();
}
The call would look like:
doSth( &function );
When passing function pointers between different classes you should create a typedef for each function pointer and use qualifiers for each function identifier.
Just define an interface that lists all the functions of all the objects that you want to reference by the pointer, but the type of this pointer should not be void, but the name of this interface instead.
Then you will be able to call every function of every object that you want by this pointer, but make sure that all structures and classes of the objects implement all the functions of the interface!
This is also important to write the : public and then the name of the interface in the header of every structure and class!

creating objects from template class with different type

I was not really sure how to formulate my question, but here is the puzzle I am trying to resolve:
if (config.a)
myObject = new Object<DummyInterface>();
else
myObject = new Object<RealInterface>();
so the task is to create a object with a dummy interface if it is specified in config, otherwise use real interface class.
How do I declare myObject then?
there are couple options, I could have Object class to derive from abstract class without templates: i.e.:
class Base
{
...
}
template <class T>
class Object : public Base
{
...
}
Then I could declare myObject as:
Base* myObject;
But here is the problem: what if my Object class declares a non virtual method:
template <class T>
class Object : public Base
{
public:
T getInterface() { return myInterface;}
private:
T myInterface;
}
I cannot call it like this:
myObject->getInterface()
and I cannot do dynamic cast, because I don't know the type until the runtime...
Any suggestions how to get around it? Maybe there is a another solution?
One way around is to use the visitor pattern. This way, your base class may implement a visit() method and your derived instances can override...
For example..
SomeComponent
{
template <typename T> // I'm being lazy here, but you should handle specific types
void handle(T& cInst)
{
// do something
}
};
class Base
{
public:
virtual void visit(SomeComponent& cComp) = 0;
};
template <class T>
class Object : public Base
{
public:
virtual void visit(SomeComponent& cComp)
{
cComp.handle(*this);
}
};
Now you can do this
SomeComponent c;
Base* obj = new Object<int>;
obj->visit(c);
And c will get the correct type.
if (config.a)
myObject = new Object<DummyInterface>();
else
myObject = new Object<RealInterface>();
This construction is incorrect in terms of the polymorphism.
Two template instantiations are two different classes. The best situation is when you have something like that:
template <class T> SomeClass: public SomeBaseClass
{
};
.........
SomeBaseClass* myObject;
But it brings you no profit.
The simplest and right solution is the virtual functions. The visitor pattern seems useful too.
I actually think that the visitor pattern would be misused here. Instead, this is a classic switch-on-types code smell that is best handled by polymorphism.
When you say "what if one derived class has an additional method to call", that is assuming a specific design. That is not a functional requirement. A functional requirement would be "what if one of the two objects created had to do behavior X during event Y". Why is this different? Because there are a number of ways to implement this that don't require more interface (though maybe more methods).
Let me show an example.
You have your factory
std::map<ConfigValue, Generator> objectFactory_;
That you've registered a bunch of generators for (probably in constructor of class)
RegisterGenerator(configValueA, DummyGenerator);
RegisterGenerator(configValueB, RealGenerator);
...
And at some point you want to create one of those objects.
shared_ptr<Base> GetConfigObject(ConfigFile config)
{
return objectFactory_[config.a]();
}
And then you want to use the object for handling an event, you can do
void ManagingClass::HandleEventA()
{
theBaseObjectReturned->HandleEventAThroughInterfaceObject(this);
}
Note how I passed a this pointer. This means if you have one object that doesn't want to do anything (like make that extra behavior call) that your managing class may provide, it doesn't need to use this.
Object<DummyInterface>::HandleEventAThroughInterfaceObject(ManagingClass *)
{
// just do dummy behavior
}
And then if you want to do something extra (call a new behavior) it can do it through that pointer in the RealInterface
Object<RealInterface>::HandleEventAThroughInterfaceObject(ManagingClass * that)
{
that->DoExtraBehavior();
// then dummy - or whatever order
// you could even call multiple methods as needed
}
That's the basic approach you should always take when dealing with polymorphism. You should never have two different code paths for different types except through calls to virtual dispatch. You should never have two different code blocks, one that calls methods A, B, and C and another that only calls A and D when dealing with a base object, depending on type. Instead, always make the derived objects do the work of figuring out what to do - because they know who they are. If you need to do stuff in the managing object, pass a this pointer for them to work with.

Getting OOP right

Ok, this is my problem. I have the following classes:
class Job {
bool isComplete() {}
void setComplete() {}
//other functions
};
class SongJob: public Job {
vector<Job> v;
string getArtist() {}
void setArtist() {}
void addTrack() {}
string getTrack() {}
// other functions
};
// This were already implemeted
Now I want to implement a VideoJob and derived it from Job. But here is my problem. I also have the following function witch it was set to work only with SongJob:
void process(SongJob s)
{
// not the real functions
s.setArtist();
..............
s.getArtist();
.............
s.getArtist();
...............
s.setArtist()
}
Here I just want it to show that the function uses only derived object methods. So if I have another object derived from Job, I will need to change the parameter to Job, but then the compiler would not know about thoose functions and I dont what to test for everyone what kind of object it is and then cast it so I can call the correct function.
So it is okay to put all the functions in the base class, because then I will have no problem, but I don't know if this is correct OOP, if one class deals with Songs and the other with videos, I thing good oop means to have 2 clases.
If I didn't make myself clear, please say so and I will try explaining better.
And in short words, I want to use polymorfism.
It is totally fine to put all the things that the classes SongJob and VideoJob have in common into a common base-class. However, this will cause problems once you want to add a subclass of Job that has nothing to do with artists.
There are some things to note about the code you have posted. First, your class Job is apparently not an abstract base class. This means that you can have jobs that are just jobs. Not SongJob and not VideoJob. If you want to make it clear that there can not be a simple Job, make the base-class abstract:
class Job {
virtual bool isComplete() = 0;
virtual void setComplete() = 0;
//other functions
};
Now, you cannot create instances of Job:
Job job; // compiler-error
std::vector<Job> jobs; // compiler-error
Note that the functions are now virtual, which means that subclasses can override them. The = 0 and the end means that subclasses have to provide an implementation of these functions (they are pure virtual member functions).
Secondly, your class SongJob has a member std::vector<Job>. This is almost certainly not what you want. If you add a SongJob to this vector, it will become a normal Job. This effect is called slicing. To prevent it, you'd have to make it a std::vector<Job*>.
There is much more to say here, but that would go to far. I suggest you get a good book.
In your Base class Job you could add those methods as virtual methods so that a class deriving from Job may or may not override these specific methods.
In your SongJob class you override the methods and dont override them in VideoJob
In, void process() pass a pointer to Base class Job
void process(Job *s)
It will then call the appropriate methods depending on the adress of the objec s is pointing to which will be a SongJob object.
In C++, you have to do two things to get polymorphism to work:
Access polymorphic functions by a reference (&) or pointer (*) to a base type
Define the polymorphic functions as virtual in the base type
So, change these from:
class Job {
bool isComplete() {}
void setComplete() {}
};
void process(SongJob s)
{
// ...
}
To:
class Job {
public: // You forgot this...
virtual bool isComplete() { }
virtual void setComplete() { }
};
void process(Job& s)
{
// ...
}
If you can't define all the functionality you need inside process on your base class (if all the member functions you'd want don't apply to all the derived types), then you need to turn process into a member function on Job, and make it virtual:
class Job {
public:
virtual bool isComplete() { }
virtual void setComplete() { }
virtual void process() = 0;
};
// ...
int main(int argc, char* argv[])
{
SongJob sj;
Job& jobByRef = sj;
Job* jobByPointer = new SongJob();
// These call the derived implementation of process, on SongJob
jobByRef.process();
jobByPointer->process();
delete jobByPointer;
jobByPointer = new VideoJob();
// This calls the derived implementation of process, on VideoJob
jobByPointer->process();
return 0;
}
And of course, you'll have two different implementations of process. One for each class type.
People will tell you all sorts of "is-a" vs "has-a" stuff, and all sorts of complicated things about this silly "polymorphism" thing; and they're correct.
But this is basically the point of polymorphism, in a utilitarian sense: It is so you don't have to go around checking what type each class it before calling functions on it. You can just call functions on a base type, and the right derived implementation will get called in the end.
BTW, in C++, virtual ... someFunc(...) = 0; means that the type that function is defined in cannot be instantiated, and must be implemented in a derived class. It is called a "pure virtual" function, and the class it is defined on becomes "abstract".
Your problem comes from the fact you're calling a process method on an object. You should have a method Process on the Job class and override this method in your derived classes.
use pure virtual functions:
class Job
{
virtual string getArtist() =0;
};