Friends,
Can a base class reference be used to access derived class-specific members? Note that the members are not part of the base class, only part of the derived class.
Thank You,
Paramesh.
Printable View
Friends,
Can a base class reference be used to access derived class-specific members? Note that the members are not part of the base class, only part of the derived class.
Thank You,
Paramesh.
The direct answer is no. If you have an object of the base class and you wish to access members of a child class of that base class then you cannot access them as the object you have is not of that object type and the data does not exist.
...and a need to do so indicates a probable flaw in the design.
It cannot access them directly, but a call to the base-class function may invoke calls in the derived class, either if the function called is virtual or if the function itself calls virtual functions.
If you are sure the reference is actually a reference to the derived class, you can use static cast, like that:Quote:
Originally Posted by cegparamesh
However, doing such thing is often due to a design flaw.Code:static_cast<Derived*>(&reference_variable)->DerivedMember(arguments);
If the base class contains one or more virtual functions (pure or not), you can use dynamic_cast as debugging purposes : it returns NULL if the reference is not actually a reference to the derived class, thus it checks logical bugs.
I don't like this usage of dynamic_cast in a release project. However it may be used in a project compiled in debug mode.
Thank You friends.
How would i use the static cast?
When i do like this, error message comes up.
Thank you,Code:Base *b = static_cast<Derived*>(&reference_variable)->DerivedMember(arguments);
Paramesh.
What is your exact code?
What does the DerivedMember returns?
Here is the code:
Thank You,Code:#include <iostream>
using namespace std;
class base
{
public:
virtual void printbase()
{
cout<<"Inside the base class..."<<endl;
}
};
class derived:public base
{
public:
void printderived()
{
cout<<"Inside the derived class..."<<endl;
}
};
int main()
{
base *s = new base();
s->printbase();
delete(s);
derived d;
base *as = static_cast<derived*>(&d)->printderived();
getchar();
getchar();
return 0;
}
Paramesh.
It depends what reference_variable is? If it is of type Base&, you can doQuote:
Originally Posted by cegparamesh
If reference_variable is of type Base* it is pretty similar:Code:Derived & d = static_cast<Derived&>(reference_variable);
d.DerivedMember(argument);
However, if it of type Base, then you have casted your Derived object to an object of class Base and there is no way to cast it back.Code:Derived * d = static_cast<Derived*>(reference_variable);
d->DerivedMember(argument);
I've heard and read this a lot, but cannot really agree that using static_cast implies a design flaw.Quote:
Originally Posted by SuperKoko
I often have members of different classes in a container (vector, map, ...) and want to do an operation on members of one type only. The typical way of doing that for me, is to loop through the container, check the type of an object
and, if it is of the type I want, static_cast it and perform the operation.
Now there are a lot of operations, which are specific to the derived classes and declaring them all for the parent class (and defining them empty) would imho unnecessarily blow up the parent class.
An example:
Now I know, there are ways to implement this without static_cast, but are those really better ways? Should class FileSystemObject really have member functions for everything that the derived objects are capable off? I don't think so.Code:class FileSystemObject
{
virtual bool isFolder() const = 0;
// ...
}
class Folder : public FileSystemObject
{
// ...
virtual bool isFolder() const { return true; }
vector<FileSystemObject*> contents;
}
class File : public FileSystemObject
{
// ...
virtual bool isFolder() const { return false; }
}
// Find all files under Folder basefolder that match a criterion
template <typename F>
vector<File*>* find(Folder* basefolder, F criterion, vector<File*>* result = 0)
{
if (! result) result = new vector<File*>;
vector<File*>::iterator it = basefolder.contents.begin();
while( it != basefolder.contents.end() {
if ( (*it)->isFolder() ) {
find(static_cast<Folder*>(*it), criterion, result);
} else {
File * f = static_cast<File*>(*it);
if (criterion(f)) result->push_back(f);
}
++it;
}
return result;
}
Please note that the above code is writte for demonstration of why I use static_casts, and thus ignores things like data encapsulation, public/private declaration and there are certainly typos as well.