当前位置: 首页 > 知识库问答 >
问题:

将派生类传递给基函数

欧阳嘉
2023-03-14

我无法将派生类传递给接受基类作为参数的函数。基类由“障碍物”组成,这些障碍物将被放置在“板”上。无效的board::setvalue(int-length、int-width、board

但是,这会导致编译器给出“未知参数转换…”错误。在浏览站点时,我发现我应该将派生对象作为常量进行传递,但这会导致问题,因为无法将常量分配给线路板(因为它包含指向非常量障碍物的指针)。
反过来,将线路板更改为包含常量障碍物会导致项目中其他地方出现很多问题,尤其是操作员

有没有办法将这些对象传递为non-consts或分配为non-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类标题

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个答案

戚峻
2023-03-14

这里的问题是您试图传递一个常量值(Player(data,moveable,x,y))作为参考。你不能那样做。关于将对象存储在阵列游戏场中的事实,您应该明确使用指针或更好的共享ptr,并将其存储在std::liststd::vector中,以避免删除问题。

拓拔野
2023-03-14

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

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

设置三重指针

Obstacle *** playfield;

这种设计有几个不好的原因,但这里有一个主要的原因:当你想通过Board::playfield调用它时,一点也不清楚okacle是否还活着。没有人确保玩家不会被长期摧毁,你将很难记录这个事实。

相反,我建议你让董事会拥有这些障碍。因此,不是障碍原始指针,而是设置唯一指针的向量,

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

(我已经把场几何放在一边了,我怀疑把它和障碍物的实际存储混合在一起是否有用——但是如果你仍然想,你可以使用向量的向量或者带有二维索引方案的单个向量)。

回到你的意图:用上面的方法,你直接摆脱了所有的一致性问题。你也可以。董事会拥有这些东西,可以用它做你想做的事。

 类似资料:
  • 问题内容: 我有一个类A,具有抽象方法doAction(BaseClass obj),期望类型为BaseClass的参数 现在,我还有另一个需要扩展A的类B。但是,B的doAction方法需要使用对象DerivedClass来扩展BaseClass。 当我需要将DerivedClass类型的参数传递给需要BaseClass的方法时,该如何处理呢? 谢谢! 问题答案: 您使基类通用: 以及使用派生类

  • 我正在尝试按房间类别(手术室或技术室)返回过滤后的

  • 我为什么要这样做?因为lambda表达式生成的ClosureType不是默认可构造的。通过这个“技巧”,我可以默认构造这样的closureType。 此外,模板参数的要求是,它必须为空=>

  • 问题内容: 我有一个C函数声明如下: 如今,我的cython包装器代码使用了numpy数组中的缓冲区语法: 我想使用新的memoryview语法,我的问题是,使用memoryview时如何将指针传递给数据? 我试过了: 当我尝试编译模块时,出现了“无法将类型’long [:]’分配给’long *’”的错误。有没有什么方法可以在调用C函数之前将指针传递给numpy数组而不将其强制转换为numpy数

  • 和构造函数类似,析构函数也不能被继承。与构造函数不同的是,在派生类的析构函数中不用显式地调用基类的析构函数,因为每个类只有一个析构函数,编译器知道如何选择,无需程序员干涉。 另外析构函数的执行顺序和构造函数的执行顺序也刚好相反: 创建派生类对象时,构造函数的执行顺序和继承顺序相同,即先执行基类构造函数,再执行派生类构造函数。 而销毁派生类对象时,析构函数的执行顺序和继承顺序相反,即先执行派生类析构

  • 主要内容:构造函数的调用顺序,基类构造函数调用规则前面我们说基类的成员函数可以被继承,可以通过派生类的对象访问,但这仅仅指的是普通的成员函数, 类的构造函数不能被继承。构造函数不能被继承是有道理的,因为即使继承了,它的名字和派生类的名字也不一样,不能成为派生类的构造函数,当然更不能成为普通的成员函数。 在设计派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数完成,但是大部分基类都有 private 属性的成员变量,它们在派生类中无法