Access derived class' functions through pointer (C++) - c++

Here's an example of the situation:
CAnimal *poTest = new CDog();
When I write "poTest->" All I can see are functions from the base class (in example: CAnimal) and not the ones in the derived one. How can I access these?

You've declared poTest as a CAnimal.
So it makes sense that you'll only see what a CAnimal can see.
If you want to use methods that a CDog uses, declare it so.

CDog * test = new CDog();
test->someFunction();
CAnimal *poTest = new CDog();
static_cast<CDog *>(poTest)->someFunction();
I'm assuming CDog (what's with the C prefix btw) inherits CAnimal. The compiler cannot know that your poTest variable happens to be a CDog - it can only see that it is a CAnimal. So, you can't call a member function of CDog with a variable of type CAnimal * - you need to convert the pointer to a CDog *, this tells the compiler to "treat this as a CDog".

In general in such a case you should only be using the interface of the base class and that function wouldn't be accessible. If you're trying to use the derived interface, consider storing a pointer to CDog instead of CAnimal. Instead of trying to get to the child methods, make your parent interface appropriate.
If you really know that your pointer points to a dog you can downcast although this may be a design smell in some cases:
CDog* cdog = dynamic_cast<CDog *>(poTest); // Safer
if(cdog)
{
cdog->someFunction();
}
static_cast<CDog *>(poTest)->someFunction(); // Faster

Since you declare poTest being an CAnimal, you can just call functions defined in CAnimal. Usually this is enougth since the base class should expose the method needed as virtual functions, dealing with a CAnimal instance and having to cast a CDog usually signal that there is something to improve in the design.

dynamic_cast<CDog*>(poTest)->CDogSpecificFunction();

Either define it as a dog:
CDog *poTest = new CDog();
Or use a cast:
static_cast<CDog*>(poTest)->bark();
Or, as per some of the other answers use one of the other casting functions/operators. In general, however, making heavy use of casts is considered bad practice; this is one of the reasons why many mainstream languages offer generics (see e.g., here).

Related

C++ assigning an object to another class

I am trying to create a pointer to a class as follows.
ASTNode* pAssign = new ASTAssignmentNode();
However, pAssign does not consist of the variables defined in class ASTAssignmentNode . Am I missing out on something here? How can I access the variables defined in ASTAssignmentNode() ? ASTAssignmentNode() inherits from ASTStatementNode() which inherits from ASTNode().
When writing pAssign->variable (which is declared in ASTAssignmentNode()) an error occurs "pAssign does not contain definition for member variable"
I am not experienced in C++.
Would appreciate any help.
You should use ASTAssignmentNode* pAssign instead. If you're doing this for a class assignment and they give you files you aren't supposed to modify that make you utilize ASTNode*, ask your TA about it because I've been in that situation and there should be workarounds you can use but it will differ from different assignments.
Try casting to access variables belonging to ASTAssignmentNode class
((ASTAssignmentNode* ) pAssign)->variable
What I have used is called a regular cast. You may also use static cast or dynamic cast has mentioned by M.M. If you want a detailed breakdown of which type of cast you need, check out a post here.
As long as you are certain ASTAssignmentNode is a child of ASTNode there should be no implications.
When you cast ASTAssignmentNode to ASTNode it will only contain the class definition for ASTNode and it knows nothing about ASTAssignmentNode. That is why you need to cast it back.
An exception to this are virtual functions. Virtual functions call the child class implementation if they exist.
Since pAssign is a pointer to the base class, you will need to cast it to the derived class, ASTAssignmentNode. Preferably with a c++ dynamic_cast.
dynamic_cast<ASTAssignmentNode*>(pAssign)->variable

C++ inheritance pattern

I am after your opinion on how best to implement an inheritance pattern in C++. I have two base classes, say
class fooBase{
protected:
barBase* b;
};
class barBase{};
where fooBase has a barBase. I intend to put these classes in a library, so that wherever I have a fooBase it can use its barBase member.
I now intend to create a specialisation of these in a specific program
class fooSpec : public fooBase{};
class barSpec : public barBase{};
Now I want fooSpec::b to point to a barSpec instead of a barBase. I know that I can just initialise b with a new barSpec, but this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?
Is there another way that this is often acheived?
Cheers.
Create a method in your specclass to cast the b into the special version.
That way instead of casting it all the time, it looks like a getter.
On the other hand OO is about programming towards interfaces and not objects. So what you are doing here looks like programming towards objects. But the is difficult to see as this example is purely theoretical.
You may consider the template solution:
template <class T>
class fooBase{
protected:
T* b;
};
and then use it as
class fooSpec : public fooBase<barSpec>{};
while ordinarily, the base would be used as fooBase<barBase>.
Is this what you want?
Normally we create a function that has the cast and returns the pointer -- and use that instead of the member directly.
Now I want fooSpec::b to point to a barSpec instead of a barBase.
There's no such thing as fooSpec::b. b belongs to fooBase, and your new class fooSpec is a (specialization of) a fooBase. You can't change the fact that b, a fooBase member, is of type barBase. This is a property of all the instances of fooBase that you can't invalidate in the particular subset of instances concerned by your specialization.
I know that I can just initialise b with a new barSpec, but this would
require me to cast the pointer to a barSpec whenever I wanted to use
specific functions in the specialisation wouldn't it?
Yes and no. Yes, you need to do that cast; but no, you don't need to do it every time. You can encapsulated in a function of fooSpec.
Is there another way that this is often acheived?
Not that I'm aware of.
this would require me to cast the pointer to a barSpec whenever I wanted to use specific functions in the specialisation wouldn't it?
That depends on whether the method you are trying to invoke is defined in the superclass and whether it is virtual.
You need to cast the pointer before invoking a method if one of the following is true...
The method belongs to the subclass only
The superclass has an implementation of the method and the subclass's implementation does not override the implementation in the superclass. This amounts to a question of whether the function is a virtual function.
Avoid data members in non-leaf classes, use pure virtual getters instead. If you follow this simple rule, your problem solves itself automatically.
This also makes most non-leaf classes automatically abstract, which may seem like an undue burden at first, but you get used to it and eventually realize it's a Good Thing.
Like most rules, this one is not absolute and needs to be broken now and then, but in general it's a good rule to follow. Give it a try.
If it looks too extreme, you may try one of the design patterns that deal with dual hierarchies such as Stairway to Heaven.

Dynamically pass the type name to a static_cast

Is it possible to dynamically choose the type you wish to cast to, during runtime?
For example, suppose I have:
ClassType * pointer=static_cast<ClassType*>(baseClassPointer);
At run time, however, I'd like to choose what the ClassType is, rather than having to hardcode it into the function.
Is this possible? The two ways I'm thinking I'd want to use it is either passing an actual char * that contains the name of the type I want to use, or somehow extracting the type information from an existing class and using that as the cast.
The reason I want to do this, is I have several derived classes from a common base class. I can get the basic functionality of the base class for each of the derived classes, but if I want a pointer to access some of the specific functionality that only exists in the derived class, I need to cast that pointer as such. And I'd like to have a function that allows me to do this casting dynamically for any of the derived classes.
Templates might be able to serve your purpose here for whenever you need it to statically cast upwards.
template <typename TTo> derived_cast ( BaseClass* b ) {
static_assert( std::is_base_of<BaseClass, TTo>::value, "You can't cast to a class that's not derived from BaseClass!" );
return static_cast<TTo*>( b );
}
The syntax becomes a bit more compressed then:
Derived* d = derived_cast<Derived>( b );
The static_assert to makes sure TTo is actually derived and such.
Now, for run-time, you'd have to use dynamic_cast, but that involves other things than what the code you have up there implies.
EDIT: Beyond this point are dragons of a crazy kind.
In C++, dynamically casting and operating on an object (without ever knowing that type at compile-time) is impossible, save for using a robust base class or if/else on some kind of run-time identifier to then provide static type information. In almost all cases, you would be better to just use a virtual method on a base class and then override them in derived classes. Switching on strings and other things is not only slow but painful when you have to keep adding extra cases: do not do it. However, if you are going to ignore my advice, here's some built-in pieces you can work with to get sort of what you want:
typeid - an operator that defines an implementation-defined, but unique-to-the-class, object (type_info) that compares uniquely to that class. You can compare them typeid( Dog) == typeid( Dog ) and get true/false correctly. This will allow you some run-time typing information.
dynamic_cast - a cast that fails on up-casting or to a class of a certain type (abridged definition, for more information see cppreference on dynamic_cast). You can use this to dynamically cast pointers and other such things, with it returning null on failure to cast. It might help you here, but you still need to know the types statically that you're working with (after switching on, say, typeid).
With these two, you could do a better implementation of what you see in the other answer with the string usage. But that's about it. Anything else requires things like boost::variant, a stronger base class, or a different design. A stronger base class sounds like what you could use here, but I can't say with 100% certainty.
Good luck!
Bad design spotted !
What about overriding your derived classes ? You are messing with something really dangerous
If you have for example base class Animal, and you have derived classes Dog and Cat, you can always cast Animal to Dog or Cat (if you know which it is):
void doCustomOperation(Animal *animal, string runtimeDecision) {
if (runtimeDecision == "dog") {
((Dog *)animal).bark();
}
if (runtimeDecision == "cat") {
((Cat *)animal).chaseMouse();
}
}
Even if you could do this at runtime (which I don't think you can), what would you do with the derived class pointer you get back? You wouldn't know at the time you write the code what type of object you'll get back so how would you know what methods you can call?
I think you would be better off either adding virtual methods to your base class to capture the necessary functionality or alternatively you could employ the Visitor Pattern.

multiple inheritance and polymorphism

my dizzyCreature class inherits from both a creature class and a dizzy class. It is also part of a polymorphic collection of creature classes. If I know that my object in the creature class is a dizzyCreature, is there a way to call a function from the dizzy class?
I have tried
creature[2].dizzyCreature::someFunction();
and
dizzyCreature::creature[2].someFunction();
and neither works. Any ideas?
If I understand correctly what you have is something like this: list<Creature*>. This list contains some dizzyCreature instances. On those instances you want to call methods of dizzy class. If this is the objective then you can use dynamic_cast to achieve this. Lets say you have Create* pCreature then you can do:
dizzyCreature* pDizzyCreature = dynamic_cast<dizzyCreature*>(pCreature);
if(pDizzyCreature )
{
pDizzyCreature->someDizzyClassMethod();
}
You need to first check if the class is of the correct type, then cast it using dynamic_cast, as has already been suggested. This solution is elegant since the dynamic cast itself does the type-checking - i.e. it will return NULL if you try to make an invalid cast. (There is no need to use typeid)
As a side note, if I were you, I'd attempt to do whatever it is you're trying to do without multiple inheritance if possible. Multiple inheritance can open up a whole can of worms and is best avoided unless there is no other alternative.

What are the disadvantages of "upcasting"?

The purpose of an abstract class is not to let the developers create an object of the base class and then upcast it, AFAIK.
Now, even if the upcasting is not required, and I still use it, does it prove to be "disadvantageous" in some way?
More clarification:
From The Thinking in C++:
Often in a design, you want the base class to present only an
interface for its derived classes. That is, you don’t want anyone to
actually create an object of the base class, only to upcast to it so that
its interface can be used. This is accomplished by making that class
abstract,
By upcasting, I meant: baseClass *obj = new derived ();
Upcasting can be disadvantageous for non polymorphic classes. For example:
class Fruit { ... }; // doesn't contain any virtual method
class Apple : public Fruit { ... };
class Blackberry : public Fruit { ... };
upcast it somewhere,
Fruit *p = new Apple; // oops, information gone
Now, you will never know (without any manual mechanism) that if *p is an instance of an Apple or a Blackberry.
[Note that dynamic_cast<> is not allowed for non-polymorphic classes.]
Abstract classes are used to express concepts that are common to a set of (sub-)classes, but for which it is not sensible to create instances.
Consider a class Animal. It does not make sense to create an instance of that class, because there is no thing that is just an animal. There are ducks, dogs and elephants, each of which is a subclass of animal. By formally declaring the class animal you can capture the similarities of all types of animals, and by making it abstract you can express that it cannot be instantiated.
Upcasting is required to make use of polymorphism in statically typed languages. This is, as #Jigar Joshi pointed out in a comment, called the Liskov Substituion Principle.
Edit: Upcasting is not disadvantageous. In fact, you should use it whenever possible, making your code depend on super-classes(interfaces) instead of base-classes(implementations). This enables you later switch implementations without having to change your code.
Upcasting is a technical tool.
Like every tool it is useful when used correctly and dangerous / disadvantageous if used inconsistently.
It can be good or bad depending on how "pure" you want your code to be in respect to a given programming paradigm.
Now, C++ is not necessarily "pure OOP", not necessarily "pure Generic", not necessarily "pure functional". And since C++ is a "pragmatic language", it is not in general an advantage force it to fit a "one and only paradigm".
The only thing that can be said, in technical terms, is that,
A derived class is a base class plus something more
Referring a derived through a base pointer makes that "something more" not accessible, unless there is a mechanism in the base to make you jump into the derived scope.
The mechanism C++ offers for that implicit jump are virtual functions.
The mechanism C++ offers for explicit jump is dynamic_cast (used in downcasting).
For non-polymorphic objects (that don't have any virtual method) static_cast (to downcast) is still available, but with no runtime check.
Advantages and disadvantages derive from consistent and inconsistent use of all of those points together. Is not a matter related to downcast only.
One disadvantage would be the obvious loss of new functionality introduced in the derived class:
class A
{
void foo();
}
class B : public A
{
void foo2();
}
A* b = new B;
b->foo2(); //error - no longer visible
I'm talking here about non-virtual functions.
Also, if you forget to make your destructors virtual, you might get some memory leaks when deleting a derived object via a pointer to a base object.
However all these can be avoided with a good architecture.