Inheritance in C ++

Here is my problem: I have a virtual method defined in the .h file that I want to call in a class that inherits from the base class. Unfortunately, the method in the derived class is not 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 is 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 like this:

 string ofxSndObj::createFilter(ofxBaseSndObj obj) { string str = obj.getType(); if(str.compare("ofxSOBuzz") == 0) { printf(" all is well "); } } 

In the above method, I need to be able to pass one of many kinds of objects that extend the xBaseSndObj object. Any suggestions or pointers would be greatly appreciated. Thanks!

+6
c ++ inheritance oop
source share
6 answers

Change this line:

 string ofxSndObj::createFilter(ofxBaseSndObj obj) 

to

 string ofxSndObj::createFilter(ofxBaseSndObj& obj) 

What you do is pass by value (copy transfer).

This means that you are copying an object to a function. Since 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 known as slicing ).

The solution should follow the link.

If you do not want the function to modify the object (perhaps that is why you passed by value so that it could not change the original), then pass the link const.

 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 "); } } 
+25
source share

You need to pass createFilter instance as a pointer (or links) to the object. You pass by value , and this forces the compiler to copy the derived object that you use as an argument into an instance of the base class. When this happens, you lose the fact that it was originally derived.

As written, your code should not compile since the declaration ofxBaseSndObj :: getType does not return anything. Did you mean this is an abstract method or return an empty string?

If you made it an abstract method, then the compiler will complain about trying to create an instance of the abstract class in the ofxSndObj :: createFilter method.

+10
source share

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

+2
source share

Creating a copy constructor and an = private statement is an effective way to prevent this error from happening again.

For example:

 class ofxBaseSndObj { public: virtual string getType(){} string key; private: ofxBaseSndObj(const ofxBaseSndObj& rhs); ofxBaseSndObj& operator=(const ofxBaseSndObj& rhs); }; 

Unless there is another good reason, you should use C ++ built into RTTI. Then you can use the typeid operator. Check your compilers' documentation to enable this if it is not enabled by default.

+2
source share

Others considered the problem of cutting. Then you ask: "Well, let me say, I know that I need to do something to determine the base type, but is there something more elegant than looking at enum to determine the type of an inherited object?

Querying and including an object type is a poor design that misses the OO approach point.

Instead

 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 interesting behavior a virtual function:

 class ofxBaseSndObj { public: // get rid of getType() virtual void HelpCreateFilter() = 0; }; string ofxSndObj::createFilter(ofxBaseSndObj& obj) { // Let the derived class do it 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 to be modified if future derived classes ofBaseSndObj are added to the system. Your version needs to be expanded for each new derived class. If this is unclear, try posting a little more code - I cannot tell from your code or class names what these functions should do.

+1
source share

You can use dynamic_cast or type_id

-one
source share

All Articles