TilesWithData
è pubblicamente derivato da Tiles
, quindi può essere assegnato a un puntatore (intelligente o stupido) di tipo Tiles
(il mio C ++ è un po 'arrugginito, ma in pratica dovrebbe essere valido)
Tiles *tiles = new TilesWithData();
Disabilitare tiles->AddTile(123)
violerebbe il Principio di sostituzione di Liskov (vedi qui ), poiché un client che ha un puntatore a un'istanza Tiles
(che si tratti di un% attuale di% di co_de o di una% diTiles
) non saprebbe di non chiamare TilesWithData
.
Se esiste una funzionalità comune, potresti introdurre una classe base astratta per entrambi
class Tiles
{
public:
virtual vector<int> GetTiles() = 0;
}
da cui puoi ricavare AddTile
class SimpleTiles : public Tiles
{
public:
void AddTile(int x) { tiles_.push_back(x); }
std::vector<int> GetTiles
{
return tiles_;
}
private:
std::vector<int> tiles_;
}
e SimpleTiles
class TilesWithData : Tiles
{
public:
void AddTile(int x, double data)
{
tiles_.push_back(x);
data_.push_back(data);
}
std::vector<int> GetTiles
{
return tiles_;
}
std::vector<double> GetData()
{
return data_;
}
private:
// elided
}
In questo modo, i dati (interni) della tua classe sono incapsulati e sei libero di cambiare l'implementazione interna effettiva senza violare i client del tuo codice. Inoltre, qualsiasi cliente, in possesso di un riferimento a TilesWithData
può essere sicuro delle sue capacità: Ottenere l'elenco delle tessere. Tutto ciò che è ulteriore dipende dai derivati.
Note: c'è ancora molto spazio per miglioramenti. Le implementazioni Tiles
non sono né pesce né carne, non forniscono una vera logica, ma non sono né semplici raccolte. Un modo migliore potrebbe essere abstrac tiles
class Tile
{
public:
virtual void Update() = 0;
}
e una singola raccolta per contenere tutti i tipi derivati da Tiles
class Tiles
{
public:
void AddTile(std::shared_ptr<Tile> tileToAdd)
{
tiles_.push_back(tileToAdd);
}
void UpdateTiles()
{
for(std::vector<std::shared_ptr<Tile>>:iterator it = tiles_.begin(); it != tiles_.end(); it++)
{
(*it)->Update();
}
}
private:
std::vector<std::shared_ptr<Tile>> tiles_;
}
Ora puoi implementare diversi tipi di tessere adatti alle tue esigenze
class SimpleTile : public Tile
{
public:
SimpleTile(int whatever)
{
// ...
}
void Update()
{
// ...
}
// ...
}
class TileWithData : public Tile
{
public:
TileWithData(int whatever, double data)
{
// ...
data_ = data;
}
void Update()
{
// ...
}
// ...
}
Dichiarazione di non responsabilità: Potrebbe darsi che ci siano alcuni errori nella sintassi C ++. Se la mia intenzione è chiara, sentitevi liberi di modificare, otherwith, per favore lasciatemi un commento.