How to avoid C++ cast for specific class methods? Design Pattern? - c++

Suppose I have something like this:
class Father {
public:
virtual int genericMethod (void) =0;
};
class Son1: public Father {
public:
int genericMethod ()
{ }
};
class Son2: public Father {
public:
int genericMethod ()
{ }
int specifClassMethod()
{ }
};
In the main I do the following:
Father * test = new Son2();
test->specifClassMethod(); //Can't do this! It is specific of Class Son2 and is not a virtual method in class Father!
The main question here is to know the better way to access Son2 specific method through Father interface. I want to know if there is a Design Pattern to solve this or another way. I don't wanna to do casts and I don't wanna to put lots of 'if' in my code.
Regards,
Eduardo

Maybe the Visitor-Pattern is the pattern you're looking for.
How Visitor Pattern avoid downcasting

Possible approach is to have specific interface with optional methods, and virtual method to get this interface in the base class (which may return zero):
class SpecificInterface {
public:
virtual ~SpecificInterface()
{ }
virtual int specifClassCmethod() = 0;
{ }
};
class Father {
public:
virtual int genericMethod (void) = 0;
virtual SpecificInterface* getSpecificInterface (void) =0;
};
class Son1: public Father {
public:
int genericMethod ()
{ }
SpecificInterface* getSpecificInterface (void)
{ return 0; }
};
class Son2: public Father, public SpecificInterface {
public:
int genericMethod ()
{ }
int specifClassCmethod()
{ }
SpecificInterface* getSpecificInterface (void)
{ return this; }
};
Usage is following:
Father * test = new Son1();
SpecificInterface * specificAPI = test->getSpecificInterface();
if( specificAPI )
specificAPI->specifClassCmethod();

You couldn't legally solve this with a cast, either, because "test" is pointing to a Father object, not a Son2 object. Casting object types means "Trust me, compiler, this variable actually holds X". It doesn't somehow magically convert a base object into a derived object; it only tells the compiler something you already know that it does not.
If you want behavior that differs by derived class, then move the behavior into a virtual method -- i.e., the code that wants to call specificCLassMethod() belongs in a virtual method of Father.

No. To call methods which only exist in a child class, you'll have to cast to the ch ild class.
While you could create a map which maps function names to functions, add your functions to it from the child class' constructor and then use something like test->callMethod("name"); you'd have to make all those methods have the same signature or use varargs to pass arguments which is not very nice.

You can static_cast<Son2*>(test)->specifClassCmethod(); but that only works if Father * test = new Son2();

If you really have something specific to Son2 then dynamic_cast<> is what you should use. If it is something that could be added as a virtual function to the base class with a default empty behaviour, then you can solve your issue without a cast (but that is not what you wanted to do as you stated in the question)
One design pattern to solve your issue is to use a proxy object. That object would have all the methods susceptible to be called and delegate them to the real object or not.
Advantages of the proxy pattern:
you concentrate the logic needed to differentiate the objects behind to one place
you can add some logging easily
the client code remains simple and the Son classes clean from extra stuff

First of all,you can not create an instance for the class "Father" because it is an abstract class(which has virtual int genericMethod (void) =0; -pure virtual function).Instead an instance can be assigned to it....
Like
Son1* obj_son = new Son1();
Father* obj = obj_son;
//now if you call generic method - son1 method will be called(Father method is over ridden)
obj->genericMethod();
//similarly for son2 class
Son2* obj_son2 = new Son2();
Father* obj2 = obj_son2;
obj2->genericMethod();
obj2->specifClassCmethod();

Related

Copy constructor call C++

So I am quite confused about copy constructors in C++. I have the following code:
class creature /* abstract class*/
{
private:
string name;
int longevity;
creature_society * cs;
public:
creature(int,int,int,creature_society*);
//creature(const creature&);
virtual ~creature();
virtual int is_a_good() =0;
};
class good_creature : public creature
{
public:
good_creature(int,int,creature_society*);
//good_creature(const good_creature&);
~good_creature();
int is_a_good() //returns 1
};
class bad_creature : public creature
{
public:
bad_creature(int,int,creature_society*);
//bad_creature(const bad_creature&);
~bad_creature();
int is_a_good(void); //returns 0
}
So I have an abstract class called creature , a good_creature and a bad_creature which are a children class of creature .
At my program I also have an array called society which has type of creature* objects. If my creature through a condition is defined as good, I allocate space for it and store it in society array as good_creature. The same happens for bad creature. I construct it as described in the following code:
society = new creature*[M];
for(i=0;i<M;i++)
{
if(condition)
society[i] = new good_creature(L,good,this);
else
society[i] = new bad_creature(L,bad,this);
}
So I have to make a pure virtual function: creature::clone(int position) which if it's either a good_creature or a bad_creature, it has to delete the society[pos] and make a copy of the society[pos-1] through a copy constructor.
So for example my good_creature::clone(int position) is like this:
void good_creature::clone(int position)
{
int cop_pos=position -1; //getting the position before that in order to copy it
delete society[pos];
society[pos] = new good_creature( *society[cop_pos] );
//....
}
I get an error because society[cop_pos] is of type creature*. I tried casting it to good creature but unfortunately I keep getting errors. Is it because I am not calling the copy constructor right, is it because I am not casting right? Any ideas? This has been buffling me for 2 days. Keep in mind I' m a newbie and might have done something wrong.
Also I don't need to define my own copy constructor since all the elements in society[i] point at the same object that is defined by creature_society * cs, so I'm trying to use the default constructors since I do not need deep copy.
Thanks for your time.
UPDATE
A class I forgot to mention and the way I construct society
class creature_society
{
private:
int N; // number of the creatures we want to be made in society
creature ** society;
public:
creature_society(int,int);
~creature_society();
};
You don't know if society[cop_pos] is the correct type, so you cannot safely cast. A better solution is to use a virtual function to create a copy
class creature {
public:
virtual creature* clone() const = 0;
...
};
class good_creature {
public:
good_creature* clone() { return new good_creature(*this); }
...
};
//Similar for bad_creature (and any other derived classes)
In your case you'd call it like this:
society[pos] = society[cur_pos]->clone();
There's no need to know the type of the object you're cloning. The virtual function call takes care of that for you. Note that good_creature::clone returns a good_creature* instead of a creature*. This is a valid overload. A virtual function overload is allowed to return a derived class. In this case you could have it return a creature* as well.
Use polymorphism and virtual dispatch to do the work for you.
Define a clone virtual function in creature class.
class creature
{
virtual creature * clone() = 0;
}
and then override it in children:
class good_creature: public creature
{
virtual creature * clone() override
{
return new good_creature(*this);
}
}
and similar for bad_creature.
Then use it:
society[pos] = society[pos - 1]->clone();
Side note: your design seems to influenced by languages like Java. This is not a (modern) C++-style. For example, in modern C++ ownership is better expressed by unique_ptr instead of pointers. This would make code cleaner and much safer.
The problem is that society is an array of creature, not of good creature, so the copy constructor doesn't apply.
You can define a constructor for good_creature and for bad_creature taking as argument a creature:
good_creature(const creature&);

what is the difference between polymorphism and inheritance

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

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).

Simple inheritance problem in 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.

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());