公共成员的C ++替代方案

时间:2014-08-24 11:44:52

标签: c++ class private public

考虑这个例子

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;
}

及其实施

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;
}

在主要课程中我将有:

#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();
}

如果我Car*BMWCar*Ferrari成为BuildCar的私人成员,那么整个程序都无法正常工作,因为我无法访问类{{1}的私有成员}}

我可以将它们设为私人BuildCar。我会添加一些setter和getter以便我可以访问它们,但是如果我有很多指向汽车的话呢?我必须在BuildCars中制作许多setter和getter,例如:

BuildCar

现在在我的主要课程中它将起作用

Car*GetBMW()
{
    return BMW
}

Car*GetFerrari()
{
    return Ferrari;
}

我知道将班级成员公开是一种不好的做法,但在我的例子中是怎样的?什么可以做?

2 个答案:

答案 0 :(得分:3)

这并没有回答你的问题,但设计可能会好一些。不是拥有一个处理多种类型汽车的Car类,而是拥有一个基类Car类,并让其他汽车类型继承该类。

然后CarBuilder类是所谓的factory class,它区分不同类型的汽车,但会向您返回Car个实例。

这样的东西
#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';
}

上述程序将打印

My car is a Ferrari

答案 1 :(得分:0)

好吧,如果您预定义mycars对象仅包含法拉利和宝马汽车的情况 - 您的代码绝对没问题。例如:

Car* bmw = mycars->getBMW();
Car* ferrari = mycars->getFerrari();

bmw->ChangeSpeed();
// etc.

但请考虑你有十辆车。在这种情况下,std::vector<Car*>可能是更好的选择,尽管您可以通过数字ID来引用汽车。

最重要的是,有很多方法可以在适当的C ++中编写你想要的东西(这是海市蜃楼:)。您可以使用或不使用指针编写,使用智能指针或引用,地图,矢量,数组等。只要你学习C ++ - 只要你知道它就是最好的方法。