通过向量移动类对象

时间:2015-04-15 09:07:33

标签: c++ class object vector

我正在设计一个必须能够停靠和卸载船只的港口系统。该港口有3个码头,每个码头有10行,包含10个泊位等。我正在使用这样的类。

class ship
{
public:
    std::string name;
    std::string size;
private:
    void dock();
    void undock();
};

class berth
{
    std::vector<ship> ships;
    std::string size;
    bool inUse;
    ship _ship;
public:
    /*void dock();
    void undock();*/
};

class row
{   
    std::vector<berth> berths;
    bool full;
public: 

};

class dock
{
    std::vector<row> rows;
    bool full;
public: 
};

class port
{
    std::vector<dock> docks;
    bool full;
public:

};

通过矢量将船舶物体移动到泊位的最佳方法是什么,以便将其停靠在那里。使用类和向量的新手,任何方向都会被贬低。

2 个答案:

答案 0 :(得分:0)

通过稍微更改代码可以轻松实现对接:

class ship
{
public:
    ship(std::string name_) : name(name_) { }
    std::string name;
};

class berth
{
public:
    berth() : ships(10, 0) { }
    std::vector<ship *> ships;
};

class row
{   
public:
    row() : berths(10) { }
    std::vector<berth> berths;
};

class dock
{
public:
    dock() : rows(10) { }
    std::vector<row> rows;
};

class port
{
public:
    port() : docks(3) { }
    void Dock(ship * ship_, int dockId, int rowId, int berthId, int shipId)
    {
        docks[dockId].rows[rowId].berths[berthId].ships[shipId] = ship_;
    }
    void Undock(int dockId, int rowId, int berthId, int shipId)
    {
        docks[dockId].rows[rowId].berths[berthId].ships[shipId] = 0;
    }

    std::vector<dock> docks;
};

int main()
{
    port port_;

    ship titanic("Titanic");

    port_.Dock(&titanic, 0, 0, 4, 2); 

    return 0;
}

首先,您需要一些方法来初始化端口的所有大小。它可以使用构造函数完成。例如,berth() : port() : docks(3) { }使用3个停靠点初始化端口(调整vector<dock> docks的大小以保留docks[0]docks[1]docks[2]元素,这些元素是您在端口中的停靠点)。接下来你需要一些信息,有一艘船停靠在泊位的确切位置。它可以通过几种方式完成,但是,我改变了船只矢量以保持指向船只的指针。因此,如果berth[i]中没有船只,则会有0,否则会有指向该船的指针。因此,要正确初始化泊位,其构造函数看起来像berth() : ships(10, 0) {}。这意味着泊位有10个放置船只的地方,0指针放在其中任何一个。现在最后一步是使Dock / Undock方法在港口操纵船只。您可以通过矢量索引访问它们。 这很简单。然而它是C ++并且在港口的水中有一些鲨鱼。在创建程序时,您应该决定谁是船舶的所有者。逻辑上港口不是船东,它不能制造或销毁船舶,它只能提供有关什么船停靠在哪个泊位的信息。因此,我决定在停泊处指挥船只并在其他地方装船。在这种情况下,您需要使用端口和船舶预防措施。如果你摧毁一艘停靠的船只并且不在港口更新有关它的信息,它将导致你的程序发生灾难。例如,我们可以通过以下方式修改main中的代码:

int main()
{
    port port_;

    {
        //titanic is constructed
        ship titanic("Titanic");

        port_.Dock(&titanic, 0, 0, 4, 2);

    }//titinic has drown (destructured)

    ship * docked_ship = port_.docks[0].rows[0].berths[4].ships[2];
    if(docked_ship != 0) //points to already destroyed object!
        cout << "Ship with name : " << docked_ship->name << " is docked in the port"; //program crash

    return 0;
}

事情变得非常糟糕。所以要注意并考虑对象的生命周期和指向它们的指针。

答案 1 :(得分:0)

我认为泊位和船只之间存在一对一的关系,虽然我发现你在泊位内有一个矢量,我不太明白。我还假设一艘船并不关心它的分配。

您可以做的是创建一个生产者 - 消费者场景,其中每个泊位都是一个资源单位,并且生产了#34;通过您的港口和每艘船舶消费&#34;一个单位的资源。让每个泊位知道它对应哪个(码头,行,位置),即添加一些内部数据。

您可以使用可用泊位制作一个队列 -

std::queue<Berth> free_berths;

http://www.cplusplus.com/reference/queue/queue/

-------&GT;对于每一个传入的船,你free_berths.pop()从队列中停泊并停靠()。如果队列为空,这意味着没有更多可用的插槽,您可以根据需要处理此案例。

&lt; -------对于每艘卸船的船只()你将free_berths.push()释放的泊位重新排入队列。

通过这种方式,您可以将逻辑与关于有多少码头,行,泊位的任何细节分开,即使它们以相同的方式组织。

===============

这个框架可以很容易地扩展到更复杂的用例场景:

1)通过使用同步代码包装来处理修改队列,使生产 - 消费关系成为多线程。此外,您可以为船舶添加单独的队列:

std::queue<Ship> incoming_ships;

多个线程可以写入和中间件线程不断尝试pop()并匹配来自free_berths和incoming_ships的条目。

2)如果您想优先使用某些码头/行的泊位,可以使用

std::priority_queue<Berth, "some_comparator"> free_berths;

而是通过基于停靠/行号创建比较器,并且作业是通过设计完成的。

http://www.cplusplus.com/reference/queue/priority_queue/priority_queue/