If I have a base class and a derived class, such as:
class Base {
protected:
int a;
public:
void setA(int);
void getA(int);
}
class Derived : public Base {
private:
int b;
public:
void doThing();
}
Then a third, additional class that uses the base class:
class OtherClass {
public:
Base doClassThing(Base*, Base*);
}
What's the best way to pass the derived class to a function that's defined to return a base class and take the base class as an argument. Like this:
Derived *x = new Derived();
Derived *y = new Derived();
doClassThing(x, y);
Would I pass the objects with a type cast? Or should I type cast the objects when they're first created?
To answer your two questions:
You would not cast the objects when they're first created.
There is no need to cast when calling; You do not need to modify the code in your question.
Related
I am trying to get my Base class instance and cast it to the derived class type. Since I can only get a const reference of my base class instance, I struggle to get it cast correctly. Does anyone have an idea?
class Base
{
};
class Derived : public Base
{
};
Base someBaseInstance;
const Base& GetBase()
{
return someBaseInstance;
}
int main()
{
Derived& derived = static_cast<Base&>(GetBase());
return 0;
}
You must declare your instance as a Derived object. It can be referenced and passed as it's Base, but must be declared as Derived:
Derived someDerivedInstance;
Also, to convert between Base and Derived, you should use dynamic_cast<>:
Derived &derived = dynamic_cast<Derived&>(GetBase());
Here in the code i am able to successfully point a derived class pointer to a base class object and I m also able to set and get value of the base class private member. If this is not giving any issues then what is the need of virtual functions and the whole confusion around run time polymorphism/late binding/vtable bla bla bal!!!
#include <iostream>
using namespace std;
class Base
{
int a;
public:
Base(int x=0):a(x){}
void setValueForMember(int p)
{
a=p;
}
void showValueOfMember(){cout<<endl<<a<<endl;}
};
class Derived:public Base
{
int b;
public:
Derived(){}
Derived(int y):b(y){}
void setValueForMember(int q)
{
b=q;
}
void showValueOfMember(){cout<<endl<<b<<endl;}
};
int main()
{
Derived D;
D.setValueForMember(10);
Derived *Dptr = new Derived();
Dptr = &D;
Dptr->showValueOfMember();
Base B;
Dptr = (Derived*)&B;
Dptr->setValueForMember(20);
Dptr->showValueOfMember();
return 0;
}
Virtual function is used in the case when , we want to access the members of the derived class using the pointer of type, base class.
when you will use
Bptr=&D;
you won't be able to access the members of Derived class , except the members inherited from the Base class.
If you want to access the members of the Derived class using the same pointer that is Bptr, you must have to use virtual function,
and at the time of compilation it is decided that which function is going to be executed, that's why it is known as
Run-Time polymorphism or Dynamic Binding
.
I have a base class
class base {
public:
base();
int someData;
virtual void foo(){
std::cout << someData;
}
};
and a few derived classes like
class derived : public base {
public:
derived();
void foo(){
std::cout << someData * 5;
}
};
Basically they have the same kind of data but the operations on this data are different.
I have another class that doesn't need to know the details of my object, all it needs to do is to set data and call the derived foo().
class useData {
public:
useData();
base x;
int do() { x.someData = 5; return x.foo(); }
};
I want "useData" to be as generic as possible so I'm using the base class instead of the derived class in its definition.
Of course in this scenario it will call the base method and not the derived one. How can I rewrite my code or make it automatically (without type checking or similar) call the derived method?
Thank you
To use polymorphism you need some pointer or references. So in useData the variable x should be declared as a base *. Afterward, you can create is using a new with any derived class. Polymorphism will perform as expected..
I have following
class base
{
};
class derived : public base
{
public:
derived() {}
void myFunc() { cout << "My derived function" << std::endl; }
};
now I have
base* pbase = new derived();
pbase->myFunc();
I am getting error myFunc is not a member function of base.
How to avoid this? and how to make myFunc get called?
Note I should have base class contain no function as it is part of design and above code is part of big function
If you are adamant that this function should NOT be a part of base, you have but 2 options to do it.
Either use a pointer to derived class
derived* pDerived = new derived();
pDerived->myFunc();
Or (uglier & vehemently discouraged) static_cast the pointer up to derived class type and then call the function
NOTE: To be used with caution. Only use when you are SURE of the type of the pointer you are casting, i.e. you are sure that pbase is a derived or a type derived from derived. In this particular case its ok, but im guessing this is only an example of the actual code.
base* pbase = new derived();
static_cast<derived*>(pbase)->myFunc();
myfunc needs to be accessible from the base class, so you would have to declare a public virtual myfunc in base. You could make it pure virtual if you intend for base to be an abstract base class, i.e one that cannot be instantiated and acts as an interface:
class base
{
public:
virtual void myfunc() = 0; // pure virtual method
};
If you ant to be able to instantiate base objects then you would have to provide an implementation for myfunc:
class base
{
public:
virtual void myfunc() {}; // virtual method with empty implementation
};
There is no other clean way to do this if you want to access the function from a pointer to a base class. The safetest option is to use a dynamic_cast
base* pbase = new derived;
....
derived* pderived = dynamic_cast<derived*>(pbase);
if (derived) {
// do something
} else {
// error
}
To use the base class pointer, you must change the base class definition to be:
class base
{
public:
virtual void myFunc() { }
};
I see no other way around it. Sorry.
You could add it as a member of base and make it a virtual or pure virtual function. If using this route however, you should also add a virtual destructor in the base class to allow successful destruction of inherited objects.
class base
{
public:
virtual ~base(){};
virtual void myFunc() = 0;
};
class derived : public base
{
public:
derived() {}
void myFunc() { cout << "My derived function" << std::endl; }
};
class Base
{
public:
virtual void foo()
{}
};
class Derived: public Base
{
public:
virtual void foo()
{}
};
int main()
{
Base *pBase = NULL;
Base objBase;
Derived objDerived;
pBase = &objDerived;
pBase->foo();
/*Here Derived class foo will be called, but i want this to call
a base class foo. Is there any way for this to happen? i.e. through
casting or something? */
}
pBase->Base::foo()
Both responses above are correct...But be careful, if you need to do that, maybe you have a big problem about the conception or the design...
You can do it through scope resolution operator ::
Something like this:
pBase->Base::foo()