Mirel
Mirel

Reputation: 29

C++ alternative to public members

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

Answers (2)

Some programmer dude
Some programmer dude

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

Zaur Nasibov
Zaur Nasibov

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

Related Questions