子对象的Ostream获取父对象的Ostream

ostream on child object takes ostream of his parent

本文关键字:Ostream 对象 获取      更新时间:2023-10-16

我有一个满是小雕像的游戏板。

分配:

board = new Figure*[boardSize];
for (int i = 0; i < boardSize; ++i) board[i] = new Figure[boardSize];
for (int i = 0; i < boardSize; ++i)
{
    for (int j = 0; j < boardSize; ++j)
    {
        FreeSpot F( i,j );
        board[i][j] = F;
    }
}

我有两个类

图:

class Figure {
  public:
        Figure          ( );
        ~Figure         ( void );
        virtual void  print ( ostream & os ) const;
        friend ostream  & operator << ( ostream & os, const Figure & F );
        int positionX;
        int positionY;
  private:
};
void Figure::print ( ostream & os ) const {
   os << "[" << positionY << "," << positionX << "]";
 }
ostream  & operator << ( ostream & os, const Figure & f ) {
   f . print ( os );
   return ( os );
 }

作为一个孩子,FreeSpot:

class FreeSpot: public Figure {
  public:
        FreeSpot            ( int, int );
        ~FreeSpot           ( void );
        virtual void print ( ostream & os ) const;
        friend ostream & operator << ( ostream & os, const FreeSpot & F );
        char shape;
  private:
};
void FreeSpot::print ( ostream & os ) const {
   os << "[" << positionY << shape << positionX << "]";
 }
 ostream  & operator << ( ostream & os, const FreeSpot & f ) {
   f . print ( os );
   return ( os );
 }

问题是,如果我试图从板中计算FreeSpot对象,它会占用图的流。

cout << board[i][j];

我做错了什么吗?非常感谢。

这是因为对象切片。

boardFigure的容器。当你这样做的时候:

    FreeSpot F( i,j );
    board[i][j] = F;

你把一个FreeSpot挤进一个Figure。F的Figure子对象将被复制到棋盘中,但是FreeSpot的特定属性将丢失。因此结果将是一个Figure

这就是为什么尽管你调用多态print(),你最终只会打印数字。

<标题> 解决方案

必须使board[][]成为指向元素的指针数组。或者更好:shared_ptr。你不会再遭受切片的痛苦。并且内存管理将更容易:

const int boardSize=8; 
vector< vector< shared_ptr<Figure> > > board(boardSize, vector<shared_ptr<Figure>>(boardSize));
for (int i = 0; i < boardSize; ++i) {
    for (int j = 0; j < boardSize; ++j) {
        board[i][j] = static_pointer_cast<Figure>(make_shared<FreeSpot>(i,j));
        cout << *board[i][j]<< " ";
    }
    cout<<endl; 
}