Inheritance in C++ - c++

Here's my problem: I have a virtual method defined in a .h file that I want to call in a class that inherits from the base class. Sadly though, the method in the derived class doesn't get called. Is there a better way to implement what I'm trying to do?
#ifndef ofxBASE_SND_OBJ
#define ofxBASE_SND_OBJ
#include "ofConstants.h"
class ofxBaseSndObj {
public:
virtual string getType(){}
string key;
};
#endif
Here's my buzz class
#ifndef OFXSO_BUZZ
#define OFXSO_BUZZ
#include "ofxBaseSndObj.h"
class ofxSOBuzz : public ofxBaseSndObj
{
public:
string getType();
};
#endif
ofxSOBuzz.cpp
string ofxSOBuzz::getType()
{
string s = string("ofxSOBuzz");
printf(" ********* returning string type %s", s.c_str()); // doesn't get called!
return s;
}
Then in another class I try to call it this way:
string ofxSndObj::createFilter(ofxBaseSndObj obj)
{
string str = obj.getType();
if(str.compare("ofxSOBuzz") == 0)
{
printf(" all is well ");
}
}
In the method above I need to be able to pass in one of many kinds of objects that all extend the ofxBaseSndObj object. Any suggestsions or pointers would be greatly appreciated. Thanks!

Change this line:
string ofxSndObj::createFilter(ofxBaseSndObj obj)
to
string ofxSndObj::createFilter(ofxBaseSndObj& obj)
What you are doing is passing by value (passing a copy).
This means you are copying the object to the function. Because the function does not know what type you are actually passing it only passes the type defined in the function declaration and thus it makes a copy of the base class (this is know as the slicing problem).
The solution is to pass by reference.
If you do not want the function to modify the object (maybe that is why you were passing by value so it could not alter the original) then pass a const reference.
class ofxBaseSndObj
{
public:
virtual string getType() const;
// If the method does not change the object mark it const
string key;
};
string ofxSndObj::createFilter(ofxBaseSndObj const& obj)
{
// allowed to call this if getType() is a const
string str = obj.getType();
if(str.compare("ofxSOBuzz") == 0)
{
printf(" all is well ");
}
}

You need to pass the instance to createFilter as a pointer (or reference) to the object. You are passing by value, and this causes the compiler to copy the derived object you use as an argument into an instance of the base class. When it does this you lose the fact that it was originally a derived type.
As written your code shouldn't actually compile since the declaration of ofxBaseSndObj::getType doesn't return anything. Did you mean for this to be an abstract method or return an empty string?
If you made it an abstract method then the compiler would complain about trying to instantiate an abstract class in your ofxSndObj::createFilter method.

This problem is called "slicing" in C++.

Making the copy constructor and operator= private is an effective way of preventing this bug from happening again.
For example:
class ofxBaseSndObj {
public:
virtual string getType(){}
string key;
private:
ofxBaseSndObj(const ofxBaseSndObj& rhs);
ofxBaseSndObj& operator=(const ofxBaseSndObj& rhs);
};
If there is no other good reason you should use C++'s built in RTTI. You can then use typeid operator. Look at your compilers documentation to turn this on if it is not on by default.

Others have addressed the slicing problem. You then ask Ok, let me say, I know I need to do something to determine the base type, but is there something more elegant than doing an enum lookup to determine the kind of inherited object?
Querying and switching on the type of the object is a poor design which misses the point of the OO approach.
Instead of
string ofxSndObj::createFilter(ofxBaseSndObj& obj)
{
string str = obj.getType();
if(str.compare("ofxSOBuzz") == 0)
{
// do ofxSOBuzz - specific thing
}
else if(str.compare("some other derived class") == 0)
{
// do stuff for other derived classes
}
// etc...
}
make the interesting behaviour the virtual function:
class ofxBaseSndObj {
public:
// get rid of getType()
virtual void HelpCreateFilter() = 0;
};
string ofxSndObj::createFilter(ofxBaseSndObj& obj)
{
// Let the derived class do it's own specialized work.
// This function doesn't need to know what it is.
obj.HelpCreateFilter();
// rest of filter creation
}
Why is this better than the original version? Because ofxSndObj::createFilter does not need modifying if future derived classes of ofxBaseSndObj are added to the system. Your version needs extending for each new derived class. If this is unclear, try to post a little more code - I can't tell from your code or class names what these functions are supposed to do.

You could use dynamic_cast or type_id

Related

Cannot assign derived raw pointer to base unique_ptr

I have some code that looks something this:
class Info {
public:
virtual bool IsHere() = 0;
virtual std::wstring GetStr() = 0;
};
class WindowsInfo : public Info {
public:
virtual std::wstring GetAnotherStr() = 0;
bool IsHere() override;
};
class AdvancedWindowsInfo : public WindowsInfo {
public:
AdvancedWindowsInfo() {}
~AdvancedWindowsInfo() {}
std::wstring GetAnotherStr() override;
std::wstring GetStr() override;
};
class InfoFactory {
public:
static Info* GetInfo();
};
class InfoManager {
public:
InfoManager();
//~InfoManager();
bool IsSomething();
private:
std::unique_ptr<Info> info;
};
InfoManager::InfoManager() {
#if WIN
info = std::make_unique<WindowsInfo>();
#else // currently no implementation Linux
info = nullptr;
#endif
}
bool InfoManager::IsSomething() {
std::unique_ptr<Info> info = InfoFactory::GetInfo();
return info && info->IsHere();
}
Info* InfoFactory::GetInfo() {
#if IS_WINDOWS
return new AdvancedWindowsInfo();
#else
return nullptr;
#endif
}
The entire code is too large (and confidential) to post here, but this snippet sums it up pretty well.
Essentially, I have a base class and some derived classes.
I also have a manager that uses a (smart) pointer to that base class.
And a Factory Method that returns the appropriate Derived object (although the signature returns a Base*).
Unfortunately, I can't get the the assignment (via the Factory Method) to work. I've tried multiple approaches but nothing works.
I tried using unique_ptr and make_unique<raw pointer>() --> it doesn't work with derived classes, only base.
I tried using unique_ptr and raw pointers --> conversion is not possible.
I tried using raw pointers (although I don't want this) and raw pointers --> it tells me that the destructor is called on the base object which is abstract. How can you call a destructor when you haven't instantiated the object (since it's an abstract class)? The compiler is contradicting itself!
Let's check the documentation for std::unique_ptr's constructors. The signature of the relevant constructor:
explicit unique_ptr( pointer p ) noexcept;
(2)
The converting constructor that converts a raw pointer to a std::unique_ptr is explicit. Among other things, this means it cannot be used for copy initialization of the form
std::unique_ptr<Info> info = InfoFactory::GetInfo();
Instead, you can use direct initialization:
std::unique_ptr<Info> info{InfoFactory::GetInfo()};
Which will allow you to perform that conversion.
While looking at this code, however, I notice that the local variable info in InfoManager::IsSomething is shadowing the class member variable InfoManager::info. If you want to change an existing std::unique_ptr so that it's now managing a new raw pointer, you might want to use reset:
info.reset(InfoFactory::GetInfo());
Ok, so I did the following:
InfoFactory::GetInfo() now returns a std::unique_ptr<Info>, as indicated by Galik
Added virtual ~Info() = default; as indicated by Nathan Pierson
Now everything seems to be working ok.
For now, I will the question unanswered as I still need to run some tests and double check some things, but basically it seems to be ok.
Thank you to everyone who made positive contibutions!

How to determine which type to dynamic_cast to?

I've been reading tutorials on dynamic_cast for a program I'm working on, and I'm not quite grasping how to utilize it.
I have multiple methods which will pass in parameters that are superclass pointers, and from there, differentiate between which is which to figure out what operations to make.
For example, the superclass might be Value, and the subclass is RationalNumber.
My plan was to set an int value ID for RationalNumber to be, I don't know, 1, and then when I use dynamic_cast, it will determine that the Value* object is actually a RationalNumber, and the operation will be performed.
How am I able to implement this?
Typical example:
class Value
{
public:
virtual ~Value();
};
class RationalNumber : public Value
{
...
}
Value *v = new RationalNumber(...)
...
RationalNumber* test = dynamic_cast<RationalNumber*>(v);
if (v)
cout << "v is a rational number" << endl;
else
cout << "v is a not rational number" << endl;
Note however that this is NOT a good solution in nearly all cases where you have inheritance. I'm writing a compiler, and it's the first time I've ever used dynamic_cast - mostly because there are some fairly generic functions that deal with (for example) ExprAST class pointers, and to add ALL of the variants of functions that all the derived classes (31 classes at present count) of has into the ExprAST would be rather unpractical. (And of course, having a call that does expr->isVariableExprAST() is not that much better than VariableExprAST* var = dynamic_cast<VariableExprAST*>(expr); if (var) ... - it's the same amount of code, more or less).
But in most cases, NOT knowing what type you deal with is a much better solution.
A more suitable solution is to use a virtual function that is common for all classes, e.g:
class Value
{
public:
virtual ~Value();
virtual void SomeMethod() = 0;
};
class RationalNumber : public Value
{
...
virtual void SomeMethod() { ... }
}
class IrrationalNumber : public Value
{
...
virtual void SomeMethod() { ... }
}
Value *v = ...
v->SomeMethod();
In this case, you will not need to do ANY checks - you just need to implement the method SomeMethod for all subtypes.
The dynamic_cast operator determines the type of an object during runtime, according to the value of the object's V-Table pointer (an implicit member field that is added to the class of the object when you have one or more virtual functions in that class).
There is nothing to implement here, and you can simply call it. For example:
bool isRationalNumber(Value* object)
{
RationalNumber* number = dynamic_cast<RationalNumber*>(object);
if (number == NULL)
return false;
return true;
}
Please note that you cannot use it on a class which does not declare at least one virtual function, as such class does not have a V-Table.
In addition, on some compilers you need to enable RTTI in the project settings.
And finally - a small suggestion (more of a personal opinion, so you may choose to ignore it):
Dynamic cast is pretty much in contrast with the concept of Polymorphism, in which you generalize objects with common attributes under a single base-class, and then refer to them using that generic base-class. With dynamic cast, you are essentially doing the opposite, as you are checking the specific type of the object before deciding what action to take.
So the suggestion is, try to avoid using it whenever possible.
If you see you have no alternatives, then check your design.
The standard way is to dynamic_cast the object to the derived class and then test if the result is null or not. For example (using your terminology):
void method(SuperClass* object) {
SubClass* subclass = dynamic_cast<SubClass*>(object);
if (subclass) {
// the object is a 'SubClass'
// do stuff...
}
}
If you have several subclasses, you'll have to check them separately. E.g.:
void method(SuperClass* object) {
SubClass_1* subclass_1 = dynamic_cast<SubClass_1*>(object);
if (subclass_1) {
// the object is a 'SubClass_1'
// do stuff...
return;
}
SubClass_2* subclass_2 = dynamic_cast<SubClass_2*>(object);
if (subclass_2) {
// the object is a 'SubClass_2'
// do stuff...
return;
}
}

Unable to access function of derived class in c++

I am trying to access a method of derived class from the object of my base class. I have a base class CBase which is an abstract class,
class CBase{
protected:
char path[255];
public:
virtual void StartBackup()=0;
void setpath(char * path)
{
strcpy(this->path,path);
}
virtual void afunc()
{
printf("Base\n");
}
};
Now two classes Ctype1 and Ctype2 are derived classes from CBase
class CType1:public CBase{
public:
void StartBackup()
{
printf("Type1:%s",path);
}
void afunc()
{
printf("CType1:afunc\n");
}
void myfunc()
{
printf("myfunc\n");
}
};
class CType2:public CBase{
public:
void StartBackup()
{
printf("Type2:%s",path);
}
void afunc()
{
printf("type2:afunc\n");
}
void typefunc()
{
printf("typefunc\n");
}
};
I have a class CManager which has an object of class CBase as its member,
class CManager{
private:
CBase * obj;
public:
CManager(){
obj = NULL;
}
~CManager(){
if(obj)
delete obj;
obj = NULL;
}
void inittype(int type)
{
if(type == 1)
{
obj = new CType1();
obj->myfunc();
}
else
{
obj = new CType2();
obj->typefunc();
}
}
};
In void inittype(int type) function i take the input as type and initialize the CBase object accordingly.
The problem that i am facing is that after creation of object when i try to access myfunc or typefunc i get compilation errors. How can i access these functions(I Dont want to create these functions in the base class)?
EDIT :
The errors that i get are,
'myfunc' : is not a member of 'CBase'
'typefunc' : is not a member of 'CBase'
Thanks
If you only need to access the classes non-derived functions at creation time, then this will work
void inittype(int type)
{
if(type == 1)
{
CType1* temp = new CType1();
temp->myfunc();
obj = temp;
}
else
{
CType2* temp = new CType2();
temp ->typefunc();
obj = temp;
}
}
If you need to access these member functions at other times, you'll need to use a cast - e.g.
CType2* child = dynamic_cast<CType2*>(obj);
Create an inittype virtual function in your base class (doing nothing), then override it in the derived classes as you need.
void CType1::inittype() {
myfunc();
}
void CType2::inittype() {
typefunc();
}
void CManager::inittype(int type)
{
if(type == 1)
{
obj = new CType1();
}
else
{
obj = new CType2();
}
obj->inittype();
}
I'm not clear what you mean by "I Dont want to create these functions in the base class".
You appear to know about pure virtual functions. If you declared the problem functions as pure functions in CBase, you should be able to call them through a CBase * pointer.
One possible confusion in object-oriented languages is that "what type is this" has two answers depending on context. When you create a new object, the type is the exact type. When you access an existing object via a reference or pointer, the type is a set of possible types - the base class and all subclasses the might exist. More precisely, the type of the pointer/reference defines the interface you can use to access the object. That interface must be known without reference to the derived classes (which may not exist when the base class is compiled) so it must be declared in the base class - the virtual methods.
If you want to call something that's only known in the derived class, there are two options. One is to not forget the derived class in the first place. For example...
CType1 *temp = new CType1();
obj = temp;
temp->myfunc();
The other is to determine which derived class you're using at run-time, and use a cast to convert the pointer. The (relatively) safe way to do this is with dynamic_cast.
CType1 *temp = dynamic_cast<CType1> (obj);
if (temp) { temp->myfunc (); }
I haven't covered how you identify the type at run-time. There's "Run-Time Type Identification" (RTTI) built into C++ to do this, but I've very rarely used it. In the rare cases where dynamic_cast is the right thing, I've always known the type for some other reason - either the objects were in a closed set of classes that could be identified via functionality in some interface anyway, or there was only one possibility that could occur in the code that needed the dynamic_cast.
The key words here are "closed set of classes" - if someone else inherits from your classes, you can have unexpected problems when objects of a type you don't know about and therefore cannot identify are accessed by your code. That isn't really a problem with OOP, it's a designed-in feature - you're supposed to be able to extend existing classes in OOP without notifying whoever wrote the base classes, that's what inheritance is for. Though in languages where you can mark a class final, that's probably a good idea if you don't want to allow it in this case (and IIRC C++11 provides a way to do that, I just don't know how to spell it).

interchangeable derived class method from base class c++

i am pretty sure this is a simple question for a long time c++ user, this should be a pattern or the problem should be solved in any other way but given i am Python developer and a total novice with c++ i don't know how it's usually done.
Suppose that i have a class where i want to store a pointer to an object that can be of 1 of two different classes that respects an interface, for example:
class AllPlayers
{
public:
virtual void play();
};
class VlcPlayer: public AllPlayers
{
public:
virtual void play();
};
class Mplayer: public AllPlayers
{
public:
virtual void play();
};
class MyMediaPlayer
{
public:
MyMediaPLayer(int playerType);
AllPlayers m_player;
};
MyMediaPlayer::MyMediaPlayer(int PlayerType)
{
if (PlayerType == 0) {
VlcPlayer tmp_player;
m_player = static_cast<AllPlayers> (tmp_player);
}
else {
Mplayer tmp_player;
m_player = static_cast<AllPlayers> (tmp_player);
}
}
MyMediaPlayer test(0);
test.play();
First, i know this would not work and that it seems pretty normal why but how could i get this effect? i would like to have a member of a class for what i am going to use ever the same methods, implemented using a interface and i would like to avoid trying to cast to every of the derived classes every time i am going to use one of his methods.
C++ is value-based, i.e., if you create an object of a given type you really have an object of this type. This doesn't play nicely with dynamic polymorphism. To get dynamic polymorphism you use a pointer or a reference to the actual object. To also get the life-time straight you typicslly allocate the corresponding object on the stack (make sure your base class has a virtual destructor if you ever release an object of a derived type using a pointer to the base). With this, you should be all set: just call a virtual function of the base class through a pointer to rhe base: When you overridethe function in the derived class this is the function which is called.
If you write
AllPlayers m_player;
that is going to be an instance of AllPlayers and cannot be an instance of a class that derives from it.
You should instead use a pointer and allocate the class on the stack.
For example:
class MyMediaPlayer
{
public:
MyMediaPLayer(int playerType);
~MyMediaPLayer();
AllPlayers m_player;
};
MyMediaPlayer::MyMediaPlayer(int PlayerType)
{
if (PlayerType == 0) {
m_player = new VlcPlayer;
}
else {
m_player = new Mplayer;
}
}
MyMediaPlayer::~MyMediaPlayer()
{
if (0 != m_player) {
delete m_player;
m_player = 0;
}
}
As suggested by #xception use of unique_ptr may relieve you from having to write code to deallocate the instance.
As correctly pointed out by #DietmarKühl you should always declare a virtual destructor in a root class (a base class that does not itself derives from some other class) as is the case with AllPlayers.
class AllPlayers
{
public:
virtual ~AllPlayers();
virtual void play(); // note: this should probably be pure virtual.
};
The reason this will not work is colloquially known as Object Splicing. (Or, for those Harry Potter readers out there, Object Splinching)
Let's look at an example:
class Foo
{
public:
int bob;
float fred;
// Foo(const Foo& otherfoo); // implicit copy constructor
};
class Bar : public Foo
{
public:
double gabe; // gabe newell is fat
char steve; // steve jobs is thin
// Bar(const Bar& otherbar); // implicit copy constructor
};
int main()
{
Foo f;
Bar b;
f.bob = 10;
f.fred = 1.5;
b.bob = 15;
b.fred = 2.5;
b.gabe = 1.77245385091; // sqrt(pi)
b.steve = -4;
f = Foo(b);
return 0;
}
This is legal and valid. Problem is, the implicit copy constructor of Foo is called, and Foo's copy constructor knows nothing about what a Bar is. Only that it contains everything a Foo has, and some extra irrelevant crap. Because of this, only the Foo's data gets preserved; the data unique to the Bar gets spliced off.
It's important to note that this is DEFINED BEHAVIOR: it's doing EXACTLY WHAT YOU TELL IT TO. Casting between a subclass of a base class and a base class is implicit. Furthermore, the behavior of the copy constructor is implicit.
It's also important to note that, under the hood, C++ pointers and references work in the same way. It's perfectly sane to pass the Bar to Foo's copy constructor by reference, this pass by reference does not produce a copy of the object. It's the same as working with a pointer.
The actual splicing takes place as a direct result of the copy constructor biting off more than it can chew. It gets an object with more state than it expected, and its only choice is to ignore the extra state.
With python, this doesn't happen because everything is implicitly stored as a reference type. Since you only work with references (the objects themselves are abstracted away), you never have the opportunity to accidentally splice an object.

Downcasting a pointer using a function instead of giant if statement

I have a vector with pointers of type Vehicle. Vehicle is the base class and there are many derived types like MotorCycle, Car, Plane, etc. Now, in my program there comes a point where I need the derived type while traversing the vector. Each Vehicle class has a GetType() function which returns an int which tells me what the derived type is (motorcylce, car, plan). So, I can use a dynamic cast to downcast to the derived type from the base class pointer. However, I need to have a giant if statement everytime I need the derived pointer
if(vehicle_ptr->GetType() == PLANE)
Plane *ptr = dynamic_cast<Plane*> vehicle_ptr;
else if (vehicle_ptr->GetType() == MOTORCYCLE)
MotorCycle *ptr = dynamic_cast<MotorCycle*> vehicle_ptr;
..and on and on.
Is there a way to have a function or some trick I can call that would save me from the giant if statement everywhere? Like ::GetDerivedPtr(Vehicle *ptr). Would a template class help here? (never used them before) Sorry, my C++ is a bit rusty and I did search but these terms bring up too much material to find what I'm looking for. Thanks.
It looks like you've manually tried to recreate polymorphism. You don't need a type member. This is almost always a bad idea. Use polymorphism and virtual functions.
When you have a vehicle pointer v and do
v->function();
It will call the proper function for whatever type (Plane, Train, or Automobile) that the pointer actually points to if function is a virtual function. What you're doing is already handled by the language.
So:
class A {
public:
virtual void f() {cout << "A";}
};
class B : public A {
public:
virtual void f() {cout << "B";}
};
int main(){
A *a;
B b;
a = &b;
a->f();
}
The above snippet will print B.
I second the idea that you need some virtual function and a common base type. Imagine that there is some way to get the pointer which has the correct type. What will you do with it then? You'll have to make a giant switch anyway, because you call specific functions for each of your specific types.
One solution would be to invent a name for the operation you are trying to execute, and put its implementation as a virtual function at each specific Vehicle class. If the operation accepts different parameter for each of the cases, the parameters have to be packed into a special polymorphic structure/class, but here maybe the Visitor pattern is a more generic solution.
First check whether what you're going to do can be done simply via virtual functions in class Vehicle, overridden by each derived class.
If not, then consider the Visitor Pattern.
Cheers & hth.,
dynamic_cast will check the type itself (you don't need your own variable for this). You can do the following instead:
Plane *plane_ptr = dynamic_cast<Plane*>(vehicle_ptr);
if(plane_ptr != NULL)
{
// Do stuff with 'plane_ptr' that you couldn't do with 'vehicle_ptr'
}
I don't really see how creating a function to do the cast would help because you still need to class specific code anyway (and the function would have a fixed return type, so the closest you could get is something like the 'dynamic_cast' call, which is pretty much a standard function anyway).
Use Visitor based dispatching. Observe that not a simple cast of any kind is required in the follwing (somewhat trivialized) example:
// simple cyclic visitor
class VehicleVistor {
public:
// add overload for each concrete Vehicle type
virtual void Visit(class Motorcycle&) {};
virtual void Visit(class Plane&) {};
virtual void Visit(class Car&) {};
};
class Vehicle {
public:
virtual Accept(VehicleVisitor&) = 0;
};
class Car : public Vehicle {
public:
virtual Accept(VehicleVisitor& pVisitor) {
pVisitor.Visit(*this);
}
};
// and so on...
At some point of you program you need to retrieve all instances of, say Motorcycle:
class MotorcycleExtractingVisitor : public VehicleVisitor {
std::vector<Motorcycle*> mMotorcycles;
public:
void operator()(Vehicle* pVehicle) {
pVehicle->Accept(*this);
}
void Visit(Motorcycle& pMotorcycle) {
mAllMotorcycles.push_back(pMotorcycle);
}
std::vector<Motorcycles*> Get() { return mAllMotorcycles; }
};
class Extractor {
public:
// here you extract motorcycles
static std::vector<Motorcycle*> ExtractMotorcycles(std::vector<Vehicle*>& pVehicles) {
MotorcycleExtractingVisitor tMotos;
std::for_each(pVehicles.begin(), pVehicles.end(), tMotos);
return tMotos.Get();
}
// this would be a templatized version, left as exercise to the reader
template<class TExtracted, classtypename TBegItr, typename TEndItr>
static std::vector<TExtracted*> Extract(TBegItr pBeg, TEndItr pEnd) {
ExtractingVisitor<TExtracted> tRequiredVehicles;
std::for_each(pBeg, pEnd, tRequiredVehicles);
return tRequiredVehicles.Get();
}
};
Usage is as follows:
// fixed type version:
std::vector<Motorcycles*> tMotos =
Extractor::Extract(tVehicleVector);
// templatized version (recommended)
std::vector<Motorcycles*> tMotos =
Extractor::Extract<Motorcycles>(
tVehicleVector.begin(),tVehicleVector.end());