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).
Related
I am confused about the concepts of inheritance and polymorphism. I mean, what is the difference between code re-usability and function overriding? Is it impossible to reuse parent class function using inheritance concept or else is it impossible to override parent class variables using Polymorphism. There seems little difference for me.
class A
{
public:
int a;
virtual void get()
{
cout<<"welcome";
}
};
class B:public A
{
a =a+1; //why it is called code reuse
void get() //why it is called overriding
{
cout<<"hi";
}
};
My doubt is about the difference between the code reuse and function overriding.
Lets start with your example.
class A
{
public:
int a;
virtual void get()
{
cout<<"welcome";
}
};
class B:public A
{
a =a+1; //why it is called code reuse
void get() //why it is called overriding
{
cout<<"hi";
}
};
Inheritance: Here you are deriving class B from class A, this means that you can access all of its public variables and method.
a = a + 1
Here you are using variable a of class A, you are reusing the variable a in class B thereby achieving code reusability.
Polymorphism deals with how a program invokes a method depending on the things it has to perform: in your example you are overriding the method get() of class A with method get() of class B. So when you create an instance of Class B and call method get you'll get 'hi' in the console not 'welcome'
Function inheritance allows for abstraction of behaviour from a "more concrete" derived class(es) to a "more abstract" base class. (This is analogous to factoring in basic math and algebra.) In this context, more abstract simply means that less details are specified. It is expected that derived classes will extend (or add to) what is specified in the base class. For example:
class CommonBase
{
public:
int getCommonProperty(void) const { return m_commonProperty; }
void setCommonProperty(int value) { m_commonProperty = value; }
private:
int m_commonProperty;
};
class Subtype1 : public CommonBase
{
// Add more specific stuff in addition to inherited stuff here...
public:
char getProperty(void) const { return m_specificProperty1; }
private:
char m_specificProperty1;
};
class Subtype2 : public CommonBase
{
// Add more specific stuff in addition to inherited stuff here...
public:
float getProperty(void) const { return m_specificProperty2; }
private:
float m_specificProperty2;
};
Note that in the above example, getCommonProperty() and setCommonProperty(int) are inherited from the CommonBase class, and can be used in instances of objects of type Subtype1 and Subtype2. So we have inheritance here, but we don't really have polymorphism yet (as will be explained below).
You may or may not want to instantiate objects of the base class, but you can still use it to collect/specify behaviour (methods) and properties (fields) that all derived classes will inherit. So with respect to code reuse, if you have more than one type of derived class that shares some common behaviour, you can specify that behaviour only once in the base class and then "reuse" that in all derived classes without having to copy it. For example, in the above code, the specifications of getCommmonProperty() and setCommonProperty(int) can be said to be reused by each Subtype# class because the methods do not need to be rewritten for each.
Polymorphism is related, but it implies more. It basically means that you can treat objects that happen to be from different classes the same way because they all happen to be derived from (extend) a common base class. For this to be really useful, the language should support virtual inheritance. That means that the function signatures can be the same across multiple derived classes (i.e., the signature is part of the common, abstract base class), but will do different things depending on specific type of object.
So modifying the above example to add to CommonBase (but keeping Subtype1 and Subtype2 the same as before):
class CommonBase
{
public:
int getCommonProperty(void) const { return m_commonProperty; }
void setCommonProperty(int value) { m_commonProperty = value; }
virtual void doSomething(void) = 0;
virtual ~CommonBase() { }
private:
int m_commonProperty;
};
Note that doSomething() is declared here as a pure virtual function in CommonBase (which means that you can never instantiate a CommonBase object directly -- it didn't have to be this way, I just did that to keep things simple). But now, if you have a pointer to a CommonBase object, which can be either a Subtype1 or a Subtype2, you can call doSomething() on it. This will do something different depending on the type of the object. This is polymorphism.
void foo(void)
{
CommonBase * pCB = new Subtype1;
pCB->doSomething();
pCB = new Subtype2;
pCB->doSomething(); // Does something different...
}
In terms of the code sample you provided in the question, the reason get() is called "overriding" is because the behaviour specified in the B::get() version of the method takes precedence over ("overrides") the behaviour specified in the A::get() version of the method if you call get() on an instance of a B object (even if you do it via an A*, because the method was declared virtual in class A).
Finally, your other comment/question about "code reuse" there doesn't quite work as you specified it (since it's not in a method), but I hope it will be clear if you refer to what I wrote above. When you are inheriting behaviour from a common base class and you only have to write the code for that behaviour once (in the base class) and then all derived classes can use it, then that can be considered a type of "code reuse".
You can have parametric polymorphism without inheritance. In C++, this is implemented using templates. Wiki article:
http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29#Parametric_polymorphism
In short, I have multiple classes that I have created for representing data from different devices (cameras, actually). They both have different behavior under the hood, but the interaction is built to be the exact same from the outside. I am trying to write a utility function that can work with either class, or presumably any more classes I write, so long as the interaction is the same. I'm pretty new to C++, so bear with me if my terminology is not exactly right.
So lets say I have these definitions for each camera.
class CamDataA
{
int getImageStart() {return ptrToStart;)
int getImageSize() {return imageSizeVariable;)
};
class CamDataB
{
int getImageStart() {return ptrToStart;)
int getImageSize() {return width*height*channels;)
};
And I want to have another separate class that can work interchangeably with either class
class imageUtils
{
//constructors/destructors
int reportSize( void* camData)
{
cout << camData->getImageSize();
}
};
But the error I get when compiling is:
error: ‘void*’ is not a pointer-to-object type
Is this even possible?
void * is an untyped pointer. To call a method of an object via pointer, the pointer must be of the appropriate type. You can explicitly cast your void * to CamDataA* or CamDataB* if you know what object it points to, but that's not what you want (you don't know the type of an object beforehand).
In your case, it's nice to use virtual methods.
1) Define an interface. I.e. define a set of methods without implementation.
class CamDataBase {
public:
virtual int getImageStart() = 0; // "=0" means abstract methods - MUST be
virtual int getImageSize() = 0; // overriden in descendants
};
The keyword virtual means that the method can be overridden in descendant classes. This means that if we have a pointer, say CamDataBase* p, and the pointer points to some descendant class, e.g. p = new CamDataA(), and if we write p->getImageStart(), then there will be a call of method that corresponds real (current) type of object (CamDataA::getImageStart()), not CamDataBase::getImageStart(), although p is a pointer to CamDataBase.
2) Now define a couple of implementations of the interface. Methods that have the same signature as virtual methods in a parent class override them.
class CamDataA: public CamDataBase {
int getImageStart() {return ptrToStart;)
int getImageSize() {return imageSizeVariable;)
};
class CamDataB: public CamDataBase {
int getImageStart() {return ptrToStart;)
int getImageSize() {return width*height*channels;)
};
3) Now define a function that accepts a pointer to CamDataBase or any of its descendants:
void reportSize(CamDataBase* camData) // using the base class
{
// type of the object and the appropriate method
// are determined at run-time because getImageSize() is virtual
std::cout << camData->getImageSize();
}
And here are several examples:
CamDataA A;
CamDataB B;
reportSize(&A); // CamDataA::getImageSize() is called
reportSize(&B); // CamDataB::getImageSize() is called
CamDataBase *p = &A;
reportSize(p); // CamDataA::getImageSize() is called
// and even if we cast pointer to CamDataA* to a pointer to CamDataB*:
reportSize((CamDataB*)&A); // CamDataA::getImageSize() is called
I hope you'll search the Web for all the words that are new to you. :)
Seems the second function is lower case whereas you defied it as upper case, and you didn't cast it to a particular object. ((CamDataA*)camData)->getImageSize...
However that is not the way to do it in C++, I would suggest you read a little more about Object Oriented...as doing the cast and using void* is very C like syntax.
With Object Oriented you can have type checking (as you can pass anything to void*) and they provide more structure and clarity to your program.
C++ (and other object oriented langauges) use Base class as a contract, that says all objects of this type should have these functions (method), so for example a base class of bag defines a method of PutItemInBag and then backpack, suitcase, handbag, etc all inherit from bag and each can have a different implementation of PutItemInBag and handle it differently, as this way outside object can handle all bags the same without having to worry which object it is, or if there is a new type of object in the system.
This is done via virtual methods - Virtual Method Overview
Then you can make the base class abstract by having an abstract virtual method
(making it = 0 in C++). This means this method has no implementation and you cannot create objects of this type. This class is only an interface (or contract) and methods that inherit from it should override this method and give their own implementation.
Abstract Classes
What you need is to have both class have a abstract base class and handle it that way..
class BaseCamData
{
virtual int getImageSize() = 0;
};
//then have both class inherit form it.
class CamDataA : public BaseCamData
{
virtual int getImageSize () {return 50;/*imagesize*/}
}
class CamDataB : public BaseCamData
{
virtual int getImageSize () {return 70;/*imagesize*/}
}
int reportSize(BaseCamData* camData)
{
count << camData->getImageSize();
}
}
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!
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());
I have two classes, one of which is a subclass of another, and differs only by the fact that it contains an additional member variable to its parent. I am not using the default constructor, passing in a reference to a single object as the constructors parameter. What I would like is for the constructor of the parent to examine this object, and then determine whether to construct an instance of the parent class (in most cases) or the subclass (in a few specialised cases).
class Superclass
{
public:
Foo foo;
Superclass(MyObject* object)
{
foo = object->GetFoo();
if(object->CreateSubclass())
{
//Create Subclass
}
else
{
//Create Superclass
}
}
};
class Subclass : public Superclass
{
public:
Barr barr;
Subclass(MyObject* object)
{
barr = object->GetBarr();
}
};
I'm aware of the factory design pattern, but don't want to have to have a factory object just for this. I'd rather duplicate the Superclass initialisation stuff into the Subclass (which seems bad) and then examine the object at each of the points where a Superclass is created and then call the appropriate constructor:
Superclass* class;
if(object->CreateSubclass())
{
class = new Subclass(obj);
}
else
{
class = new Superclass(obj);
}
Is this sort of thing possible, and if so how would I go about calling the subclasses constructor from Superclass constructor? I've tried making a call to Subclass(object), but I run into issues with both Superclass and Subclass needing to be defined before the other.
Thanks for any advice you can provide.
If you're set against a factory class, why not just a static function?
class Subclass
{
public:
static Superclass* create(const MyObject* const object)
{
if (object->createSubclass())
{
return new Subclass(object);
}
else
{
return new Baseclass(object);
}
}
// ...
}
// ...
Superclass* const myInstance = Subclass::create(myObject);
(I've put the static class in Subclass because it needs both the super and subclass implementations, but you could easily put it in a shared namespace or something, or even put the declaration in the base class but put the implementation in a cpp)
You've now got most of the benefits of a factory class, with no more code than you had before. You're just missing the ability to pass it around or easily refactor it into multiple implementations.
I think this is impossible. The object is allocated before the constructor is called. Otherwise there would be no 'this' pointer and you couldn't initialize your variables. Think about it. Also notice that constructors don't return anything, yet the output of new YourClass() is a pointer to your new object.