Inheritance and pointers in C++ - c++

I have this code example and I want to understand why it behaves the way it does. This is a question from a past exam paper in an intro C++ course. I'm studying for the exam now and trying to solidify my understanding of class inheritance.
#include <iostream>
using namespace std;
class Bird {
public:
virtual void noise() { cout << "mumble" << endl; }
void move() { noise(); cout << "fly" << endl; }
};
class Canary: public Bird {
public:
void noise() { cout << "chirp" << endl; }
void move() { noise(); cout << "flap" << endl; }
};
class Tweety: public Canary {
public:
void noise() { cout << "tweet" << endl; }
void move() { noise(); cout << "run" << endl; }
};
int main() {
Canary *yellow = new Tweety();
yellow->noise();
yellow->move();
return 0;
}
I've run this code, and the output is:
tweet
tweet
flap
Which means it's calling the Tweety implementation of noise(), but it's calling the Canary implementation of move(). I'm confused about that. I understand the idea of polymorphism, and noise() is virtual, so it makes sense that it calls the Tweety version, since *yellow is a pointer to a Tweety. But why does it call the Canary version of move()?
I think what's confusing me, is the line:
Canary *yellow = new Tweety();
This says that *yellow is a Canary pointer, which points to a Tweety object. I'm sort of ok with that, because I get that pointers to base class can point to derived class. But *yellow points to a Tweety, so why doesn't it use Tweety's move()?
Thanks in advance for any help.

noise is virtual, so it is dynamically dispatched to the Tweety implementation when you call it.
move in not virtual, so the version to call is decided at compile time based on the type of you are dispatching the call through. Since yellow is a Canary the compiler does resolve what will be called at compile time and will explicitly call the move method in Canary.

The move() should also be virtual otherwise the version of the pointer type is called.

Sean and Alex are spot on.
Here are some more call cases that should help make sense of the different scenarios.
#include <iostream>
using namespace std;
class Bird {
public:
virtual void noise() { cout << "mumble" << endl; }
void move() { noise(); cout << "fly" << endl; }
void noise2() { cout << "mumble2" << endl; }
virtual void move2() { noise2(); cout << "fly2" << endl; }
};
class Canary: public Bird {
public:
void noise() { cout << "chirp" << endl; }
void move() { noise(); cout << "flap" << endl; }
void noise2() { cout << "chirp2" << endl; }
void move2() { noise2(); cout << "flap2" << endl; }
};
class Tweety: public Canary {
public:
void noise() { cout << "tweet" << endl; }
void move() { noise(); cout << "run" << endl; }
void noise2() { cout << "tweet2" << endl; }
void move2() { noise2(); cout << "run2" << endl; }
};
int main() {
Canary *yellow = new Tweety();
yellow->noise();
yellow->move();
yellow->noise2();
yellow->move2();
return 0;
}
/* OUTPUT:
tweet <- virtual dispatch
tweet <- virtual dispatch, via Bird::move()
flap <- direct call
chirp2 <- direct call
tweet2 <- direct call, from Tweety::move2()
run2 <- virtual dispatch
*/

Related

In C++, How 'a pointer point to a parent intance' can be casted to 'a child type'?

class CParent {
public:
void Output() {
cout << "I'm Parent!" << endl;
}
virtual void VirtualOutput() {
cout << "I'm Parent!" << endl;
}
};
class CChild : public CParent {
public:
void Output() {
cout << "I'm Child!" << endl;
}
void VirtualOutput() {
cout << "I'm Child!" << endl;
}
};
class CChildChild : public CChild {
public:
void Output() {
cout << "I'm ChildChild!" << endl;
}
void VirtualOutput() {
cout << "I'm ChildChild!" << endl;
}
void CChildOnly() {
cout << "I'm only on ChildChild!" << endl;
}
};
int main() {
CParent cp;
CChild cc;
CChildChild ccc;
CParent* pCP1 = &cp;
CParent* pCP2 = &cc;
CParent* pCP3 = &ccc;
((CChildChild*)pCP1)->CChildOnly(); //<-this code actually works. HOW? WHY?
return 0;
}
The pointer variable 'pCP1' is pointing 'cp' which is 'an object of CParent'. So the 'down casting' doesn't make any sense according to what I've learned.
But it works and shows 'I'm only on ChildChild!' with no problem.
The 'cp' has only 'CParent part' on its memory construct. So it can not be 'down casted' as far as I know.
But it works. How?

c++ dynamic_cast over decorator instantiations fails

I am trying to understand how decorator pattern works and how much I can "stretch" it to me needs. Following this example, I have extended classes XYZ. There exist derived classes "KLM" (from XYZ)
Specifically, even though I have a decorator pattern, the derived decorator classes "KLM" have some functionality that does not show up in any of their base classes "XYZ", "D", "I" or "A".
So while normally I would instantiate an object as
I * inKLM = new L( new M( new K( new A )));
This would not allow me to access the K::doVirtR() , L::doVirtS() and M::doVirtT() functions (see code below). To access these I would need to downcast the inKLM pointer using dynamic_cast to each of classes "KLM".
The problem is that I only manage to do this for the leftmost new in the expression above. I have read that polymorphism needs to be maintained in order for the dynamic casting to work, so I have tried to have a virtual destructor in all functions. Still I cannot get the dynamic cast to work for anything other than the "outer" new operation (in this case object of class "L").
Please see this code. How can I make not only "LinKLM" , but also "MinKLM" and "KinKLM" success in dynamic_casting ?
#include <iostream>
#include <list>
using namespace std;
class D; //decorator base
struct I { //interface (for both Base and DecoratorBase
I(){
cout << "\n| I::ctor ";
}
virtual ~I(){
cout << "I::dtor |" ;
}
virtual void do_it() = 0;
virtual void regDecorator(D* decorator) = 0;
virtual void train() = 0;
virtual void et() = 0;
};
class D: public I { //DecoratorBase : has same-named fns as Base (must be exported on I) and calls upon them.
public:
D(I * inner) : m_wrappee(inner) {
cout << "D::ctor ";
regDecorator(this);
}
virtual ~D() {
cout << "D::dtor ";
delete m_wrappee;
}
void do_it() {
m_wrappee->do_it();
}
virtual void et() {
cout << "filling in for lack of et() in derived class\n";
} //almost pure virtual, just not implemented in all derived classes
void train(){
m_wrappee->train();
}
private:
void regDecorator(D* decorator){
m_wrappee->regDecorator(decorator);
}
I * m_wrappee;
};
class A: public I { //Base has all the basic functionality
public:
A() {
cout << "A::ctor " ;
decList.clear();
}
~A() {
cout << "A::dtor |" ;
}
void do_it() {
cout << 'A';
}
void train(){
et();
}
void regDecorator(D* decorator)
{
if (decorator) {
cout << "reg=" << decorator << " ";
decList.push_back(decorator);
}
else
cout << "dec is null!" <<endl;
}
private:
void et()
{
//size_t counter=0;
list<D*>::iterator it;
for( it=decList.begin(); it != decList.end(); it++ )
{
//if ( (*it)->et() )
(*it)->et();
//else
// cout << "couldnt et cnt=" << counter << endl;
//counter++;
}
}
std::list<D*> decList;
};
class X: public D { //DerivedDecoratorX ..
public:
X(I *core): D(core){
cout << "X::ctor ";
}
virtual ~X() {
cout << "X::dtor ";
}
void do_it() {
D::do_it();
cout << 'X';
}
void doX() {
cout << "doX" << endl;
}
protected:
virtual void doVirtR() = 0;
private:
void et(){
cout << "X::et" <<endl;
}
};
class K: public X {
public:
K(I * core):X(core) {
cout << "K::ctor " ;
}
virtual ~K() {
cout << "K::dtor ";
}
void doVirtR(){
cout << "doVirtK" <<endl;
}
};
class Y: public D {
public:
Y(I *core): D(core){
cout << "Y::ctor ";
}
virtual ~Y() {
cout << "Y::dtor ";
}
/*void et(){
cout << "Y::et" <<endl;
}*/
void do_it() {
D::do_it();
cout << 'Y';
}
void doY() {
cout << "doY" << endl;
}
protected:
virtual void doVirtS() = 0;
};
class L: public Y{
public:
L(I * core):Y(core) {
cout << "L::ctor ";
}
virtual ~L() {
cout << "L::dtor ";
}
void doVirtS(){
cout << "doVirtL" <<endl;
}
};
class Z: public D {
public:
Z(I *core): D(core){
cout << "Z::ctor ";
}
virtual ~Z() {
cout << "Z::dtor ";
}
void et(){
cout << "Z::et" <<endl;
}
void do_it() {
D::do_it();
cout << 'Z';
}
void doZ() {
cout << "doZ" << endl;
}
virtual void doVirtT() = 0;
};
class M: public Z{
public:
M(I * core):Z(core) { //must add D(core) here explicitly because of virtual inheritance in M's base class (Z).
cout << "M::ctor " ;
}
virtual ~M() {
cout << "M::dtor ";
}
void doVirtT(){
cout << "doVirtM" <<endl;
}
};
int main(void) //testing dynamic casting
{
I * inKLM = new L( new M( new K( new A )));
L * LinKLM = dynamic_cast<L *>( inKLM);
M * MinKLM = dynamic_cast<M *>( inKLM);
K * KinKLM = dynamic_cast<K *>( inKLM);
cout << endl;
if ( ! MinKLM ) cout << "null MinKLM!" << endl;
if ( ! LinKLM ) cout << "null LinKLM!" << endl;
if ( ! KinKLM ) cout << "null KinKLM!" << endl;
//KinKLM->doVirtR();
//LinKLM->doVirtS();
//MinKLM->doVirtT();
//LinKLM->D::train();
//KinKLM->do_it();
//MinKLM->doZ();
delete inKLM;
cout << endl;
return 0;
}
If you need access to functionality that is unique in some of the inner classes, you may be better off (depending on the particular problem) trying mixin classes. The basic idea is to have a template class inherit its template parameter. I have simplified the classes below but the principle is clear:
#include <iostream>
// your base class
class I {
public:
virtual void do_it() {}
};
// a decorator
template <class Base>
class T1 : public Base {
public:
void do_it() {
std::cout << "T1" << std::endl;
Base::do_it();
}
void unique_in_T1() {
std::cout << "Unique in T1" << std::endl;
}
};
// another decorator
template <class Base>
class T2 : public Base {
public:
void do_it() {
std::cout << "T2" << std::endl;
Base::do_it();
}
void unique_in_T2() {
std::cout << "Unique in T2" << std::endl;
}
};
// yet another decorator
template <class Base>
class T3 : public Base {
public:
void do_it() {
std::cout << "T3" << std::endl;
Base::do_it();
}
void unique_in_T3() {
std::cout << "Unique in T3" << std::endl;
}
};
int main(int argc, const char * argv[]) {
T3<T2<T1<I>>> my_object1;
my_object1.do_it();
my_object1.unique_in_T2();
T1<T3<I>> my_object2;
my_object2.do_it();
my_object2.unique_in_T3();
return 0;
}
Your class D is not needed anymore. The main purpose of that class is to wrap the object that actually does the job while maintaining the interface of I. With mixin classes there is no wrapping anymore as it has been replaced by inheritance, hence there is no need for the D class.
Here is a link to read more.

C++: simple quest., destructors being called multiple times

I am learning how to do OOP in c++. Please take a look at my simple example, and tell me if my OOP approach is incorrect.
I am looking to do this: create a "settings" type class that will be passed into a few other classes by reference. In the example this is the "ECU" class. I am using member initialization to pass the ECU class into each class. Is this the right way to do it?
Destructors in each class will delete any arrays created with the new command. In my code, the destructors for ECU are being called multiple times. If I had a "myArray" in ECU, and was using "delete[] myArray" in the ECU destructor, I would get errors. What's the right way to do this?
Also, the transmission and engine destructors are called before the program quits. Is this because the compiler knows they will not be used again?
// class_test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class ECU
{
public:
ECU()
{
cout << "ECU Constructor" << endl;
}
~ECU()
{
cout << "ECU Destructor" << endl;
}
void flash()
{
softwareVersion = 12;
}
int pullCode()
{
return softwareVersion;
}
private:
int softwareVersion;
};
class Engine
{
public:
Engine(ECU &e) : ecu(e)
{
horsepower = 76;
cout << "Engine Constructor" << endl;
}
~Engine()
{
cout << "Engine Destructor" << endl;
}
private:
ECU ecu;
int horsepower;
};
class Transmission
{
public:
Transmission(ECU &e) : ecu(e)
{
cout << "Transmission Constructor" << endl;
gearRatios = new double[6];
if (ecu.pullCode() == 12){
for (int i = 0; i < 6; i++)
gearRatios[i] = i+1.025;
cout << "gear ratios set to v12.0" << endl;
}
}
~Transmission()
{
delete[] gearRatios;
cout << "Transmission Destructor" << endl;
}
private:
ECU ecu;
double *gearRatios;
};
class Car
{
public:
Car(ECU &e) : ecu(e)
{
cout << "Car Constructor" << endl;
Engine myEngine(ecu);
Transmission myTrans(ecu);
}
~Car()
{
cout << "Car Destructor" << endl;
}
private:
ECU ecu;
};
int _tmain(int argc, _TCHAR* argv[])
{
ECU myComputer;
myComputer.flash();
Car myCar(myComputer);
system("pause");
return 0;
}
You're passing a reference, but you're not storing a reference:
ECU ecu;
means that your member will be a copy of the object that was referenced by the constructor's parameter.
If you want to store a reference, store a reference:
ECU& ecu;

How does g++ compiler know which vtable ptr to use if their are multiple vtable ptr in a base class?

I want to know know how does g++ compiler knows which table to use if their are multiple vtable present in a base class. Like the following example.
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
class sample1
{
private:
int b;
public:
sample1():b(34)
{
cout << "In sample1 constructor" << endl;
}
virtual void print_b()
{
cout << this->b << endl;
}
void print_all()
{
this->print_b();
}
void sample_print_()
{
//cout << this->a << "String : " << this->str1 << endl;
cout << "hello" << endl;
this->print_all();
}
};
class sample2
{
private:
int b1;
public:
sample2():b1(34)
{
cout << "In sample1 constructor" << endl;
}
virtual void print_b1()
{
cout << this->b1 << endl;
}
void print_all1()
{
this->print_b1();
}
};
class sample : public sample1 , public sample2
{
private:
int a;
char *str1;
public:
sample():a(12),sample1()
{
strcpy(this->str1,"hello world");
cout << "In Constructor" << endl;
}
~sample()
{
free(this->str1);
cout << "In Destructor" << endl;
}
void sample_print()
{
//cout << this->a << "String : " << this->str1 << endl;
cout << "hello" << endl;
this->print_all();
}
virtual void print_a()
{
cout << this->a <<endl;
}
};
In above example, child class sample has two parent classes sample1 and sample2 and each of these class have vtable of their own. What if i call a virtual function from sample(child class)? How does the compiler know, in which class that virtual function is present so that it call use that particular vtable pointer ? I know their will be two vtable pointer present in sample(child class) class , so how does compiler know which one to use ?

Why is my virtual method being skipped over in C++?

Long story short: The program I'm working on is a rogue like - even though that isn't really needed for this question.
Here's the hierarchy tree for my classes related to this question:
Entity
Item Creature
Weapon Armor
I have several virtual functions declared in Entity, which are also virtual in the classes derived from it.
I'm not sure how to word my question, but I'll explain the problem and post the code below. I have a factory type class, called ItemFactory, that opens an xml file and uses a simple parser that I made - and creates Item objects and sets their values. It has a method that returns an Item pointer. In my main file, I declare/define an ItemFactory object. When an Item needs to be dropped in the game, I use a pointer, that is of type, Item,
and call the method to randomly choose an Item to point to. All of this works perfectly..
Here's the problem. Entity has a virtual method called dumpObject() which prints the state of the variables it has. dumpObject() is also virtual in Item. When it's called from an Item, the method first calls Entity's dump with this:
Entity::dumpObject();
Then it dumps it's own variables.. I do the same for Weapon and Armor except using this:
Item::dumpObject();
My Question:
Since the ItemFactory holds both - Weapons and Armor, and the pointer in the main program points to an Item, shouldn't calling "itemPointer->dumpObject();" dump the values for Weapon/Armor (depending which it is pointing to..) which would also dump the values in Item which would also dump the values in Entity?
When I run the code, the only part that gets dumped is the part in Item and Entity.
Let me know if I need to provide more detail. Any suggestions? Thanks!
Here's the Code Snippets
I have the headers included, just tried to minimize the amount of code that I'm posting
Item.cpp
void Item::dumpObject(){
cout << "Item:" << endl;
dumpObjectData();
}
void Item::dumpObjectData(){
Entity::dumpObjectData();
cout << " [Weight] " << getWeight() << endl;
cout << " [Value] " << getValue() << endl;
cout << " [Quantity] " << getQuantity() << endl;
cout << " [Enchantment] " << getEnchantment() << endl;
}
Entity.cpp
void Entity::dumpObject(){
cout << "Entity:" << endl;
dumpObjectData();
}
void Entity::dumpObjectData(){
XMLSerializable::dumpObjectData(); //XMLSerialization handles parsing
cout << " [Name] " << getName() << endl;
cout << " [DisplayChar] " << getDisplayChar() << endl;
cout << " [Properties] " << endl;
for( auto it = m_vProperties.begin(); it != m_vProperties.end();it++ ){
cout << " - " << (*it) << endl;
}
}
Weapon.cpp
void Weapon::dumpObject(){
cout << "Weapon:" << endl;
dumpObjectData();
}
void Weapon::dumpObjectData(){
Item::dumpObjectData();
cout << " [Damage] " << getDamage() << endl;
cout << " [Range] " << getRange() << endl;
cout << " [Accuracy] " << getAccuracy() << endl;
cout << " [AmmoType] " << getAmmoType() << endl;
cout << " [Type] " << getType() << endl;
}
Armor.cpp
void Armor::dumpObject(){
cout << "Armor:" << endl;
dumpObjectData();
}
void Armor::dumpObjectData(){
cout << "calls to dump item data"<<endl;
Item::dumpObjectData();
cout << "calls to dump armor"<<endl;
cout << " [Type] " << getType() << endl;
cout << " [Slot] " << getSlot() << endl;
cout << " [ArmorValue] " << getArmorValue() << endl;
}
Main
ItemFactory myItems = ItemFactory::instance();
Item * pItem1 = myItems.generateItem();
pItem1->dumpObject();
Headers
Entity.h
#include "XMLSerializable.h"
#include <vector>
class Entity : public XMLSerializable {
public:
Entity(void);
virtual ~Entity(void);
virtual void dumpObject();
virtual void dumpObjectData();
};
Item.h
#include "Entity.h"
class Item : public Entity{
public:
Item(void);
virtual ~Item(void);
virtual void dumpObject();
virtual void dumpObjectData();
};
Weapon.h
#include "Item.h"
class Weapon : public Item {
public:
Weapon(void);
virtual ~Weapon(void);
virtual void dumpObject();
virtual void dumpObjectData();
};
Armor.h
#include "Item.h"
class Armor : public Item {
public:
Armor(void);
virtual ~Armor(void);
virtual void dumpObject();
virtual void dumpObjectData();
};
ItemFactory.cpp
ItemFactory & ItemFactory::instance(){
static ItemFactory myObj;
return myObj;
}
ItemFactory::ItemFactory(){
m_mtRandom.seed( time(NULL) );
fstream xmlFile;
xmlFile.open("items.xml");
vector<XMLSerializable*> pObjects;
parseXML(xmlFile, pObjects);
XMLSerializable * pObject;
for(auto it = pObjects.begin(); it != pObjects.end(); it++){
pObject = (*it);
Item * pItem = dynamic_cast<Item*>(pObject);
if (pItem != NULL){
m_vItems.push_back(pItem);
}
}
}
ItemFactory::~ItemFactory(){
}
Item * ItemFactory::generateItem() {
vector<Item*> tempItems;
for(auto it = m_vItems.begin(); it != m_vItems.end(); it++){
tempItems.push_back((*it));
}
int randomItem = (m_mtRandom() % (m_vItems.size() - 1));
Item * pItem = tempItems.at(randomItem);
Item * pReturnValue = new Item(*pItem);
return pReturnValue;
}
Now that I just did all that work, I don't think any of the code except maybe Main was necessary.. Lol I'm guessing my logic for the pointer in Main is wrong?
Well here's your problem:
Item * pReturnValue = new Item(*pItem);
This is giving you a shallow copy so that you do not get an Armor or Weapon.
If you need to do a copy given only a base class instance, define a clone method in the base class.
It looks like you are trying to use the prototype pattern, so you do want to create new instances?
class Entity : public XMLSerializable {
public:
Entity(void);
virtual ~Entity(void);
virtual Entity* clone() const { return new Entity(*this);}
virtual void dumpObject();
virtual void dumpObjectData();
};
class Armor : public Item {
public:
Armor(void);
virtual ~Armor(void);
virtual Armor* clone() const { return new Armor (*this);}
virtual void dumpObject();
virtual void dumpObjectData();
};
Note the use of covariant return values for clone(). I.e. The return values do differ but as the method signature matches and the return values are derived from one another, the call is virtual.
You then can write:
Item * pReturnValue = pItem->clone();
See: Wikipedia for background on the Prototype pattern.