2015-05-19 2 views
0

У меня есть игровая доска, полная фигурок.ostream на дочернем объекте принимает ostream своих родителей

Выделено:

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

Проблема заключается в том, что если я попробуйте cout FreeSpot objec ts от доски, он берет ostream от Рис.

cout << board[i][j]; 

Я делаю что-то неправильно? Большое спасибо.

ответ

1

Это из-за object slicing.

board является контейнером Figure. Поэтому, когда вы это сделаете:

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

вы выжимаете FreeSpot на рисунке. Подобъект изображения F будет скопирован в доску, но специальные атрибуты FreeSpot будут потеряны. Так что результатом будет Figure.

Вот почему, несмотря на ваш призыв к полиморфному print(), вы закончите печать только рисунков.

Решение

Вы должны сделать настольную [] [] массив указателей на элементы. Или лучше: 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; 
}