Edit :
The problem is in the GoFish.h file, in the constructor to
be specific, where it is trying to instantiate the players object.
The compiler throws the following error message : no member named 'noOfBooks' in 'Player'
GoFish() {players = new GoFishPlayer[2];} // Instantiate two players
Object Slicing seems to be one of the most ambiguous concepts in OOP for beginners. I have been working on this card game in C++, where I have a base class called, Player and a derived class called GoFishPlayer. When trying to access the methods of a GoFishPlayer object referenced back to a Player Object, the program tends to slice off the specific methods and attributes for the derived class, thus making it a clone of the base object. Is there any way to overcome this problem?
Game.h
Abstract class Game : which forms the foundation for both the games -
GoFish and CrazyEights
class Game {
protected:
Deck* deck;
Player* players;
int player_id;
public:
Game(){
deck = Deck::get_DeckInstance(); // Get Singleton instance
player_id = choosePlayer();
players = NULL;
}
....
}
GoFish.h
Derived Class GoFish - The Problem is here in the constructor when I am trying to instantiate a Player object derived from the Game Class
class GoFish : public Game{
static GoFish* goFish;
GoFish() {players = new GoFishPlayer[2];} // Instantiate two players
public:
static GoFish* get_GoFishInstance() {
if(goFish == NULL)
goFish = new GoFish();
return goFish;
}
Player.h
class Player{
protected:
std::string playerName;
Hand hand;
bool win;
public:
Player(){
playerName = "Computer"; // Sets default AI name to Computer
hand = Hand(); // Instatiate the hand object
win = false;
}
....
GoFishPlayer.h
class GoFishPlayer : public Player {
private:
std::vector <int> books;
int no_of_books;
public:
GoFishPlayer() {
no_of_books = 0;
books.resize(13);
}
int noOfBooks(){return no_of_books;}
void booksScored() {no_of_books++;}
bool checkHand() {}
....
The wording of your question seems ambiguous to me but as best as I understand you're trying to access methods of GoFishPlayer through a reference to a Player object? This isn't a problem caused by object slicing, it's just how polymorphism works.
You need to cast the reference of the Player object so that it becomes a reference to a GoFishPlayer object.
class Parent
{
public:
void foo() { std::cout << "I'm a parent" << std::endl; }
};
class Derived : public Parent
{
public:
void bar() { std::cout << "I'm a derived" << std::endl; }
};
int main()
{
Derived d;
// reference to a derived class stored as a prent reference
// you can't access derived methods through this
Parent& p_ref = d;
// this won't work
// p_ref.bar();
Derived& d_ref = static_cast<Derived&>(p_ref);
// this works
d_ref.bar();
}
This only works if you definitely know that p_ref is actually of type Derived, or that it is of a type that inherits from Derived. If you can't be sure you need to do a runtime check using dynamic_cast and then catch any std::bad_cast exceptions that are thrown.
Related
This question already has an answer here:
can dynamic binding happen without using pointer and using regular object in c++
(1 answer)
Closed 4 months ago.
I am trying to find a way to create a generic "car" class, with children that overload the parent's methods. Subsequently, I would like to have a user class that has as a member any class in the "car" family. Is there a way to achieve the desired functionality? Thank you!
The pseudocode below shows what my intial attempt was, but the compiler obviously complains that User wants a Car object, not a Toyota.
class Car
{
public:
Car();
void method1();
};
class Toyota : public Car
{
public:
Toyota();
void method1();
};
class Lada : public Car
{
public:
Lada();
void method1();
};
class User
{
public:
User();
Car car;
};
int main()
{
User user;
Toyota toyota;
user.car = toyota;
}
There are several ways to achieve this. One approach is to use pointers or references which allow you to use runtime polymorphism. A pointer or reference to a Car can also point to any object of a class derived from Car. However to get true polymorphism you need to declare the methods virtual. Also you really should delcare a virtual ~Car() = default destructor:
struct Car {
virtual ~Car() = default; // virtual destructor is important if you
// hold owning references or pointers that
// you want to use to destroy the object
// (like for example std::unique_ptr)
virtual void method1(); // declare this virtual if you want
// polymorphic behaviour on method1
};
struct Toyota : public Car {
void method1() override; // no need to declare this virtual because
// it is already virtual in base class.
// the 'override' would warn you if there was
// no 'virtual method1' in the base class
};
// ...
Toyota toyota;
Car& car_ref = toyota;
Car* car_ptr = &toyota;
car_ref.method1(); // calls Toyota::method1()
car_ptr->method1(); // calls Toyota::method1()
If using references or pointers you should keep in mind that they are non-owning. You must ensure, that the object that is referenced exists if you dereference the pointer or reference.
Car& f() {
Toyota toyota;
Car& car_ref = toyota;
return car_ref; // badooomz: return of reference to toyota
// that is going to be destroyed at the end
// of scope. You do not want this
}
An easy way to couple ownership to a pointer is to use std::unique_ptr:
std::unique_ptr<Car> f() {
auto toyota = std::make_unique<Toyota>();
return std::move(toyota);
}
An entirely different way to achieve your goal is to use static polymorphism (or duck typing) through std::variant:
struct Car {
void method1(); // no virtual functions needed
};
struct Toyota { // note: no inheritance here
void method1();
};
// ...
Toyota toyota;
// store a toyota in the variant
std::variant<Car, Toyota /*,...*/> car = toyota;
// call Toyota::method1()
std::visit([](auto&& car_like){ car_like.method1(); }, car);
Note that there is no relationship at all between Car and Toyota in this example. You could store any object in the variant, for which obj.method1() is a valid function call. That is why this kind of static polymorphism is called duck typing - anything that looks like a duck is treated like a duck. Note that when using std::variant you store a copy of the object and not a reference in the variant. Thus it is safe to return the variant from a function even if the original object is destroyed when leaving the function scope.
i think you should use virtual functions inside car and a reference pointer on assigning class toyota to car, the code i written below is working good.
#include <iostream>
using std::cout;
class Car
{
public:
Car(){cout << "A car";};
virtual void method1(){cout << "from car";};
};
class Toyota : public Car
{
public:
Toyota(){cout << "A toyota";};
void method1() {cout << "from toyota";};
};
class Lada : public Car
{
public:
Lada(){cout << "A Lada";};
void method1() {cout << "from lada";};
};
class User
{
public:
User(){cout << "A user";};
Car *car;
};
int main()
{
User *user = new User();
Toyota toyota;
user->car = &toyota;
delete user;
/***
if you dont need pointers then
User user;
Toyota toyota;
user.car = &toyota;
/**
}
I am trying to design a parking system (Low-level Design )
Some classes behave like this.
class Vehicle
{
public:
int entryTime;
int exitTime;
virtual void leaveParking(Vehicle*);
virtual int getChargePerHr();
//virtual void getChargePerHr() = 0;
Vehicle() {}
};
class Car : public Vehicle
{
private :
int chargePerHr = 30;
public:
void leaveParking(Vehicle*);
int getChargePerHr();
Car(){}
};
class Bike : public Vehicle
{
private :
int chargePerHr = 10;
public:
void leaveParking(Vehicle*);
int getChargePerHr();
Bike(){}
}
void Vehicle ::leaveParking(Vehicle* v)
{
int pay = v-> // Here expecting Car class member function getChargePerHr() should come
//so that I can access private member chargePerHr of car class.
// But I am not able to access the Car class member function here.
}
int main()
{
Car c1; // assume Car c1 has already parked.
Vehicle v;
Vehicle* vptr = new Vehicle();
vptr = new Car();
c1.leaveParking(vptr); // Car c1 wants to leave the parking place
}
I want to access getChargePerHr() of Car class using Base class Vehicle member function.
I tried with pure virtual function but still could not make it.
Could anyone help me?
Problem
Here:
void Vehicle::leaveParking(Vehicle* v)
{
...
}
You're not able to access Car::getChargePerHr() because v is a Vehicle not a Car.
Clearly you're attempting to achieve polymorphism since it appears you want derived classes of Vehicle to perform the same actions when they leave parking.
Solution
Declare Vehicle::getChargePerHr() as pure virtual (or virtual if you want a default implementation)
Provide implementations of getChargePerHr() in your derived classes
Implement Vehicle::leaveParking() using just the methods you've defined in Vehicle
At runtime, the virtual table will resolve overrides and call the correct derived implementation.
Other Issues
You are inheriting from Vehicle without declaring its destructor virtual. This means if any child classes need to perform clean-up, their destructors won't be called.
You're missing a semicolon after the Bike class declaration.
If every Vehicle does the same thing when leaving parking, it doesn't make sense to have leaveParking() be virtual—you make a member function virtual if you want it to be able to be overridden by child classes.
Vehicle::leaveParking() should probably not be taking another Vehicle as a parameter. The function acts on the vehicle itself, not on a different one.
If your constructor is empty, it's better to leave it out of the class declaration since it can confuse others who might read your code.
And many more issues. I suggest you take aalimian's advice to read up on C/C++. Your code shows many misunderstandings.
Code
Putting everything together, here's an example:
class Vehicle
{
public:
int entryTime;
int exitTime;
virtual ~Vehicle() = default;
void leaveParking();
virtual int getChargePerHr() = 0;
};
void Vehicle::leaveParking()
{
// This will call a derived class's implementation
int pay = getChargePerHr();
// Do more vehicle stuff
}
class Car : public Vehicle
{
private:
int chargePerHr = 30;
public:
int getChargePerHr() override;
};
int Car::getChargePerHr()
{
return chargePerHr;
}
class Bike : public Vehicle
{
private:
int chargePerHr = 10;
public:
int getChargePerHr() override;
};
int Bike::getChargePerHr()
{
return chargePerHr;
}
You can see this in action here.
Ok so I am attempting to make a component/entity system for my game engine, and I have a base class component which has the virtual method update(), and then all the different types of components are derived from that single base class. I store the pointers to these components in the an array, then loop over the array calling the update method. When I have just one type of derived class this works fine it calls the derived virtual method, but once I add a different type of derived class it starts using the base update method. Here's and example:
//Hold the pointers to the Components
Component** components;
//in the system constructor I initialize the array of components
void System::System()
{
components = new Component*[MAX_COMPONENTS]();
}
//Inputlistener is a derived component
InputListener* inputListener;
inputListener= new InputListener;
//Playercontroller is also derived component
PlayerController* playerController;
playerController = new PlayerController;
//Adds the pointer to the components array
system->add(inputListener);
system->add(playerController);
//loops over the array the update method is a virtual method
system->update(); //calls the base classes update method not the derived
From what I have read online it seam like this should be possible since the array is just holding the pointer not the object themselves so the they should be getting sliced into the base class. If I am indeed wrong about this assumption what would be a solution?
//Hold the pointers to the Components
std::vector<Component*> components;
//Inputlistener is a derived component
InputListener* inputListener;
inputListener= new InputListener;
//Playercontroller is also derived component
PlayerController* playerController;
playerController = new PlayerController;
components.push_back(inputListener);
components.push_back(playerController);
for( size_t i = 0; i < components.size(); ++i ){
Component* cmp = components.at(i);
if( cmp ) cmp->update();
}
#include <iostream>
using namespace std;
class Base {
public:
virtual void update (){
cout << "Base" << endl;
}
};
class Derived1 : public Base {
public:
void update () override{
cout << "Dervied1" << endl;
}
};
class Derived2 : public Base {
public:
void update () override{
cout << "Dervied2" << endl;
}
};
int main()
{
Base* sample[3];
sample[0] = new Base();
sample[1] = new Derived1();
sample[2] = new Derived2();
for(int i=0; i < 3; ++i){
sample[i]->update();
}
return 0;
}
I have created a link here http://codepad.org/IfnBdYIk . Can you verify your code with this and tell if you are doing anything differently ? Because from the description of what you tried, you should not have seen the incorrect behavior, neither did I.
This question already has answers here:
Polymorphism in C++
(7 answers)
Closed 9 years ago.
From past few weeks I am learning and experimenting inheritance and Polymorphism in C++.
Few syntax always confusing me to understand, mainly object calling from main function.
for eg:
#include <iostream.h>
using namespace std;
class Base
{
public:
Base(){ cout<<"Constructing Base";}
virtual ~Base(){ cout<<"Destroying Base";}
};
class Derive: public Base
{
public:
Derive(){ cout<<"Constructing Derive";}
~Derive(){ cout<<"Destroying Derive";}
};
void main()
{
Base *basePtr = new Derive();
delete basePtr;
}
Here is my question:
What actually happens when Base *basePtr = new Derive(); this syntax is called? and what are the advantages?
As per my knowledge I understood it calls derive class object and stores it in a pointer to base class object. Am I correct? If I am, why are we storing it in base class?
To clear my doubts I went through memory layout of class objects and disassembling, but it confuses me more.
Could anyone tell me how to understand this kind of syntax?
Public inheritance means that every object of the derived class IS at the same time an object of the base class (it provides all the interfaces the base class has). So, when you write:
Base *basePtr = new Derive();
new object of class Derive is created, than the pointer to it is assigned to basePtr and through basePtr you can access all the functionality Base class provides.
And if you then call any of Base class virtual functions like:
basePtr->callSomeVirtualFunction();
the function from the actual object class will be invoked, as it happens with the destructor in the end of your main function.
When you are using pointer to a base class object instead of pointer to a derived one, you are saying that you need only BASIC properties of this derived class.
Hmmm... Pointers are confusing at the beginning.
When you call Base *basePtr = new Derive();, you are creating a Derive object instance and just keeping a "bookmark" of where this object is, but with a Base pointer.
When you do that, the only accessible properties (without a cast) will be from Base class.
Why this is used? To abstract things. Imagine that you are coding something related to mugs, cups, glasses and jugs. Basically all types of those objects are make to store some kind of liquid. So I'll call the base class of LiquidContainer:
class LiquidContainer
{
//...
};
class Mug : public LiquidContainer
{
//...
};
class Glass : public LiquidContainer
{
//...
};
class Cup : public LiquidContainer
{
//...
};
class Jug : public LiquidContainer
{
//...
};
All the others are inherited from LiquidContainer, although the Jug, the Cup and the Mug could be created in a little more sophisticated inheritance tree.
Anyway, the intent of having a base class and using polymorphism is to avoid code replication and to abstract thins, allowing that all the LiquidContainer family be treated almost the same way.
Take by example a more complete class definition.
class LiquidContainer
{
public:
LiquidContainer(unsigned int capacity, unsigned int color) :
mCapacity(capacity),
mColor(color)
{
}
unsigned int getCapacity() { return mCapacity; }
unsigned int getColor() { return mColor; }
virtual char* name() = 0;
protected:
unsigned int mCapacity;
unsigned int mColor;
};
class Mug : public LiquidContainer
{
public:
Mug() :
LiquidContainer( 250, 0xFFFF0000 ) // 250 ml yellow mug!
{
}
virtual char* name() { return "Mug"; }
};
class Glass : public LiquidContainer
{
public:
Glass() :
LiquidContainer( 200, 0x000000FF ) // 200 ml transparent glass!
{
}
virtual char* name() { return "Glass"; }
};
class Cup : public LiquidContainer
{
public:
Cup() :
LiquidContainer( 50, 0xFFFFFF00 ) // 50 ml white cup!
{
}
virtual char* name() { return "Cup"; }
};
class Jug : public LiquidContainer
{
public:
Jug() :
LiquidContainer( 1500, 0x0000FF00 ) // 1.5 l blue Jug!
{
}
virtual char* name() { return "Jug"; }
};
With those class definitions you could do the following test:
#include <iostream>
#include <vector>
int main( int argc, char* argv[] )
{
std::vector< LiquidContainer* > things;
things.push_back( new Mug() );
things.push_back( new Cup() );
things.push_back( new Glass() );
things.push_back( new Jug() );
for ( auto container : things )
{
std::cout << "This is a '" << container->name() << "' with capacity of " << container->getCapacity() << "ml and color " << container->getColor() << std::endl;
}
return 0;
}
This little program outputs
This is a 'Mug' with capacity of 250ml and color 4294901760
This is a 'Cup' with capacity of 50ml and color 4294967040
This is a 'Glass' with capacity of 200ml and color 255
This is a 'Jug' with capacity of 1500ml and color 65280
I hope that this little exercise are enough to show you why the polymorphism is used.
That's called Polymorphism. It means that the object is a Derive as well as Base and can be used as both. For eg. If Dog is the subclass of Animal. Object of dog can be treated as Animal too. All dogs are animal, but not all animals are dog.
So you can call a dog an animal, that's why you can give the address of subclass object(Derive) to superclass pointer(Base). But it'll remain an object of subclass and will function like one. This is just to fool compiler into understanding that it's an object of Base.
Now the benefit is you can have a method which can accept object(or pointer in precise sense) of Base class, but can be passed any of it's subclass. The con here is you can only call methods which are in the base class and may or may not overridden in derive class.
in C++;
Is there a way of calling a function from a derived class through the base class
even when the function is not overridden? In other words, I'm using a base class in
order to have heterogeneous containers without boost; I want to call a member function
that is only specific to a derived class...
Example:
(I just made this code up so there's probably a syntax error but hopefully you get the gist)
class Vehicle
{
public:
virtual void do_vehicle_stuff();
// virtual void do_car_specific_stuff(); makes no sense here
}
class Car : public Vehicle
{
public:
void do_vehicle_stuff();
void do_car_specific_stuff();
}
Car a,b;
list<Vehicle> vehicle_list;
vehicle_list.push_back(a);
vehicle_list.push_back(b);
vehicle_list.front().do_car_specific_stuff();
error: 'Class Vehicle' has no member named 'do_car_specific_stuff()'
You are slicing your classes when you insert them into the list. In
C++ subtype polymorphism (the kind of polymorphism you are using) only
works through references or pointers but not values. When you insert
your carS into the list they are converted to VehicleS.
An example:
Car c;
std::vector<Vehicle> vs;
vs.push_back(c); // slicing happens
vs.front(); // not a car anymore, but just a vehicle,
// the Car-ness is lost through the copy operation
How do to it:
std::vector<std::unique_ptr<Vehicle>> vs;
vs.push_back(new Car());
vs.front(); // actually a Car
After you have resolved that fundamental flaw of your code, this might
help you:
Vehicle* vehiclep = new Car();
if(auto carp = dynamic_cast<Car*>(vehiclep)) {
carp->do_car_specific_stuff();
}
This is a rather costly operation and usually an indication of a
design smell, so you might want to rethink what you are doing.
Here's a more appropriate design:
struct Vehicle
{
virtual ~Vehicle() { }
void do_vehicle_stuff()
{
vehicle_impl();
}
private:
virtual void vehicle_impl() = 0;
};
struct Car : Vehicle
{
private:
virtual void vehicle_impl()
{
my_vehicle_stuff();
my_car_specific_stuff();
}
void my_vehicle_stuff() { /* what you had originally */ }
void my_car_specific_stuff() { /* car-only stuff */ }
};
std::list<std::unique_ptr<Vehicle>> vehicles;
vehicles.emplace_back(new Car);
vehicles.emplace_back(new Motorcycle);
vehicles.emplace_back(new Carriage);