首页 文章

将派生类传递给基函数

提问于
浏览
1

我将派生类传递给接受基类作为参数的函数时遇到了麻烦 . 基类由“障碍物”组成,这些“障碍物”将放置在“板”上的空板:: setvalue(int length,int width,Obstacle&obstacle);

但是,这会导致编译器给出"no known conversion for argument..." -error . 在网站周围阅读我发现我应该将派生对象作为const传递,但这会导致问题,因为const不能分配给板(因为它保存了指向非const障碍的指针) .
反过来,改变董事会以持有const障碍会导致项目其他地方出现很多问题,尤其是运营商<< Board of Board and Obstacle .
我已经尝试将对象作为consts传递然后使用Obstacle ob = new障碍物(const障碍物),但这使得它们成为通用的Obstacle对象而不是Player / Barrel / Wall对象 .

有没有办法将这些对象作为非consts传递或将它们指定为非consts?我尝试使用const_cast()但这导致了未定义的行为 .

函数调用的一个示例:

Board_->setvalue(x, y, Player(data, moveable, x, y));

这是我的代码:

基类

class Obstacle
{
    public:
    Obstacle* _properlyinitialized;
    string Name;
    bool Moveable;
    int x;
    int y;
    Obstacle();
    Obstacle(string Name, bool Moveable, int x, int y);
    virtual ~Obstacle();
    bool properlyInitialized();
    friend std::ostream& operator<<(std::ostream& stream, Obstacle& Obstacle);
};

派生类的一个示例(其他派生类还没有特殊功能)

class Player: public Obstacle
{
public:
    Player():Obstacle(){};
    Player(string Name, bool Moveable, int x, int y):Obstacle(Name, Moveable, x, y){this->_properlyinitialized = this;};
    ~Player(){};
    /*void Moveleft();
    void Moveright();
    void Moveup();
    void Movedown();*/
};

Board类 Headers

class Board
{
private:
    Board* _properlyinitialized;
    int length;
    int width;
    Obstacle * * * playfield;

public:
    /*
     **ENSURE(this->properlyInitialized(),
                "Object wasn't initialized when calling object");
     */
    Board();
    Board(int length, int width);
    ~Board();
    bool properlyInitialized();
    /*
     **REQUIRE(this->properlyInitialized(),
            "Object wasn't initialized when calling properlyinitialized");
     */
    void clear();
    const int getLength();
    const int getWidth();
    Obstacle*** getBoard();
    Obstacle* getTile(int length, int width);
    void setvalue(int length, int width, Obstacle& obstacle);
    friend std::ostream& operator<<(std::ostream& stream, Board& Board);
};

std::ostream& operator<<(std::ostream& stream, Board& Board);

最后,setvalue函数 .

void Board::setvalue(int length, int width, Obstacle& obstacle)
{
    this->playfield[length][width] = &obstacle;//value;
    return;
}

如果需要,我很乐意提供更多代码 .

2 回答

  • 0

    而不是完整的代码审查( - 这不是SO的用途),让我们直接进入您提到的例程

    void Board::setvalue(int length, int width, Obstacle& obstacle)
    {
        this->playfield[length][width] = &obstacle;
        return;
    }
    

    它设置了一个三重指针

    Obstacle *** playfield;
    

    这个设计有几个原因很糟糕,但这里有一个主要原因:当你想通过 Board::playfield 调用它时,根本不清楚ostacle还活着 . 没有人能确保玩家不会长时间被摧毁,并且你将很难记住这个事实 .

    相反,我建议你让董事会拥有障碍 . 因此,代替障碍物原始指针,设置唯一指针的向量,

    std::vector<std::unique<Obstacle> > playfield;
    

    然后复制或移动类:

    template<typename O>
    void Board::setvalue(int length, int width, O&& obstacle)
    {
        playfield.push_back(std::make_unique<O>(std::forward<O>(obstacle));
    }
    

    (我把场地几何体放在一边,我怀疑将它与障碍物的实际存储混合是有用的 - 但是如果你仍然想要你可以使用矢量矢量或一个二维矢量指数方案) .

    在这里回到你的意图: With the above approach, you directly get rid of all constness problems. 你又名 . Board 拥有这些东西,可以随心所欲地使用它 .

  • 2

    这里的问题是你尝试传递一个const值( Player(data, moveable, x, y) )作为参考 . 你不能这样做 . 关于将对象存储在数组游戏区域中的事实,您应该明确地使用指针或更好,shared_ptr并将其存储在 std::liststd::vector 中,以避免删除问题 .

相关问题