Reputation: 29
Consider this example
class Sprite
{
public:
Sprite(int imageID, int maskID);
~Sprite();
//some methods
}
Sprite::Sprite(int imageID,int maskID)
{
//this is the class for creating sprites in winapi..its doesnt matter what it has in this example
}
Sprite::~Sprite()
{
DeleteObject ( mhImage );
DeleteObject ( mhMask );
}
class Car{
public:
enum Type{
Ferrari,
BWM
};
Car(Type type);
~Car();
void InitSpeed()
void ChangeSpeed();
//..some methods
private:
Sprite *car;
}
and its implementation
Car::Car(Type type)
{
switch(type)
{
case Ferrari:
car=new Sprite("Ferrari","FerrariMask");
break;
case BMW:
car=new Sprite("BMW","BMWMask");
break;
}
}
void Car::InitSpeed()
{
speed=100;
}
void Car::ChangeSpeed()
{
speed=200;
}
Car::~Car()
{
delete car;
}
class BuildCar:public Car
{
public:
BuildCar();
~BuildCar();
Car*BMW;
Car*Ferrari;
}
BuildCar::BuildCar()
{
Ferrari=new Car(Ferrari);
BMW=new Car(BMV)
}
BuildCar::BuildCar()
{
delete Ferrari
delete BMW;
}
and in may main class I will have:
#include "Car"
class Game
{
private:
//etc
BuildCar*mycars;
//etc;
}
Game::Game()
{
mycars=new BuildCar();
mycars->BMW->InitSpeed();
mycars=>Ferrari->InitSpeed();
....
at some point i will have:
mycars->BMW->ChangeSpeed();
mycars->Ferrari->ChangeSpeed();
}
If I make Car*BMW
and Car*Ferrari
private members of BuildCar
, the whole program won't work because I can't access private members of class BuildCar
.
I can make them private and in BuildCars
. I will add some setters and getters so that I can access them, but what if I have many pointers to car? I will have to make many setters and getters in BuildCar
for example:
Car*GetBMW()
{
return BMW
}
Car*GetFerrari()
{
return Ferrari;
}
And now in my main class it will work
mycars->GetBMW()->ChangeSpeed();
mycars->GetFerrari()->ChangeSpeed();
I know its a bad practice to make class members public but how is it in my example? And what can be done?
Upvotes: 0
Views: 171
Reputation: 409136
This doesn't answer your question, but the design could be a little better. Instead of having a single Car
class that handles multiple types of car, have one base Car
class, and have the other car types inherit from that class.
Then the CarBuilder
class is a so-called factory class which distinguish between the different types of cars, but return a Car
instance to you.
Something like
#include <iostream>
#include <memory>
class Car
{
public:
Car() : speed(0) {}
virtual ~Car() {}
void setSpeed(int speed) { this->speed = speed; }
int getSpeed() const { return speed; }
virtual std::string getType() = 0;
private:
int speed;
};
struct Ferrari : public Car
{
std::string getType() { return "Ferrari"; }
};
class BMW : public Car
{
std::string getType() { return "BMW"; }
};
class CarBuilder
{
public:
enum CarType
{
Ferrari,
BMW
};
static std::unique_ptr<Car> makeCar(const CarType type)
{
switch (type)
{
case Ferrari:
return std::unique_ptr<Car>(new ::Ferrari);
case BMW:
return std::unique_ptr<Car>(new ::BMW);
default:
return nullptr;
}
}
};
int main()
{
auto myCar = CarBuilder::getCar(CarBuilder::Ferrari);
std::cout << "My car is a " << myCar->getType() << '\n';
}
The above program will print
My car is a Ferrari
Upvotes: 3
Reputation: 22659
Well, if you predefine a situation in which mycars
object contains Ferrari and BMW cars only - your code is absolutely fine. You can for example:
Car* bmw = mycars->getBMW();
Car* ferrari = mycars->getFerrari();
bmw->ChangeSpeed();
// etc.
But consider that you have ten cars. In that case an std::vector<Car*>
might be a better choice, although you would refer to the cars by their numerical ID.
The bottomline is that there are lots and lots of ways to write what you want in a proper C++ (which is a mirage :). You can write with or without pointers, with smart pointers or references, maps, vectors, arrays and so on. As long as you learn C++ - just do it the best way as you know it.
Upvotes: 0