将派生 class 传递给基函数
Passing derived class to base function
我无法将派生的 class 传递给接受基础 class 作为参数的函数。基础 class 由 "obstacles" 组成,它们将被放置在 "board" void Board::setvalue(int length, int width, Obstacle& obstacle);
但是,这会导致编译器给出 "no known conversion for argument..." 错误。在网站上阅读我发现我应该将派生的 object 作为常量传递,但这会导致问题,因为无法将常量分配给板(因为它包含指向 non-const 障碍的指针).
反过来,将 Board 更改为持有 const Obstacles 会导致项目其他地方出现很多问题,尤其是 Board 和 Obstacle 的 operator<<。
我尝试将 objects 作为常量传递,然后使用 Obstacle ob = new obstacle(the const obstacle) 但这使它们成为通用的 Obstacle objects 而不是Player/Barrel/Wall objects.
有没有办法将这些 object 作为 non-const 传递或将它们分配为 non-const?我尝试使用 const_cast() 但这导致了未定义的行为。
函数调用示例:
Board_->setvalue(x, y, Player(data, moveable, x, y));
这是我的代码:
基地class
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);
};
一个派生classes的例子(其他派生classes还没有特殊功能)
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();*/
};
董事会classheader
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;
}
如果需要,我很乐意提供更多代码。
这里的问题是您试图传递一个常量值 (Player(data, moveable, x, y)
) 作为参考。你不能这样做。关于将对象存储在数组运动场中这一事实,您应该明确使用指针或更好的 shared_ptr 并将其存储在 std::list
或 std::vector
中,以避免删除问题.
与其进行完整的代码审查(-- 这不是 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));
}
(我把场几何放在一边,我怀疑将它与障碍物的实际存储混合是否有用——但如果你仍然想要,你可以使用向量的向量或单个向量使用二维索引方案)。
回到你的意图:使用上述方法,你可以直接摆脱所有常量问题。你又名。 Board
拥有这些东西,可以随心所欲地使用它。
我无法将派生的 class 传递给接受基础 class 作为参数的函数。基础 class 由 "obstacles" 组成,它们将被放置在 "board" void Board::setvalue(int length, int width, Obstacle& obstacle);
但是,这会导致编译器给出 "no known conversion for argument..." 错误。在网站上阅读我发现我应该将派生的 object 作为常量传递,但这会导致问题,因为无法将常量分配给板(因为它包含指向 non-const 障碍的指针).
反过来,将 Board 更改为持有 const Obstacles 会导致项目其他地方出现很多问题,尤其是 Board 和 Obstacle 的 operator<<。
我尝试将 objects 作为常量传递,然后使用 Obstacle ob = new obstacle(the const obstacle) 但这使它们成为通用的 Obstacle objects 而不是Player/Barrel/Wall objects.
有没有办法将这些 object 作为 non-const 传递或将它们分配为 non-const?我尝试使用 const_cast() 但这导致了未定义的行为。
函数调用示例:
Board_->setvalue(x, y, Player(data, moveable, x, y));
这是我的代码:
基地class
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);
};
一个派生classes的例子(其他派生classes还没有特殊功能)
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();*/
};
董事会classheader
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;
}
如果需要,我很乐意提供更多代码。
这里的问题是您试图传递一个常量值 (Player(data, moveable, x, y)
) 作为参考。你不能这样做。关于将对象存储在数组运动场中这一事实,您应该明确使用指针或更好的 shared_ptr 并将其存储在 std::list
或 std::vector
中,以避免删除问题.
与其进行完整的代码审查(-- 这不是 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));
}
(我把场几何放在一边,我怀疑将它与障碍物的实际存储混合是否有用——但如果你仍然想要,你可以使用向量的向量或单个向量使用二维索引方案)。
回到你的意图:使用上述方法,你可以直接摆脱所有常量问题。你又名。 Board
拥有这些东西,可以随心所欲地使用它。