I ran into a little problem when coding some stuff. I am wondering if the following situation is a good place to use C++ friendship, this would be my first time I've needed to use it. Another lengthy post, thanks in advance if you read this. =)
First off:
As I understand it, "const" should be used at the end of a function declaration to mean that it cannot modify its member values. So naturally I put const at the end of my save function, since it only
uses the member data to save a file, but doesn't
modify it.
Basically, I have a World class with a save() function, and this save function saves some header data + the data for each Tile object in the World.
The issue is that World::save() needs to call each Tile's save(), but I do not want the user to be able to do something like
world.getTiles()[0].save(f) in their own (main or whatever) function.
This is how I have my trimmed program set up after adding const
1 2 3 4 5 6 7 8 9 10
|
class Tile {
public:
Tile();
void save() const; //notice it's public, to be called from World::save()
};
Tile::Tile() {}
void Tile::save() const
{
std::cout << "Tile saved to file!\n";
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
class World {
public:
World();
void save() const;
const std::vector<Tile>& getTiles() const;
private:
std::vector<Tile> mTiles;
};
World::World()
: mTiles(10) {}
void World::save() const
{
//save "header" stuff (not shown)
//save each tile:
for (int i = 0; i < mTiles.size(); i++)
mTiles[i].save();
}
const std::vector<Tile>& World::getTiles() const
{
return mTiles;
}
|
1 2 3 4 5 6 7 8
|
int main()
{
World world;
world.save();
world.getTiles()[0].save(); //This is technically legal,
//but I don't want it to be.
return 0;
}
|
Here is the modified Tile class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
class Tile {
friend class World;
public:
Tile();
private:
void save() const; //private, but World can still call it
};
Tile::Tile() {}
void Tile::save() const
{
std::cout << "Tile saved to file!\n";
}
...
world.getTiles()[0].save() //is now compile-time error (which is good)
|
Again, to reiterate, I'm just wondering if this a good use case for friendship or is my design flawed?
PS: Another method that "works" is to keep World::save() const, but make Tile::save() non-const, so that the compiler still gives an error, but this is just screaming bad practice to me, so friendship seems like the best choice here?
Thanks for reading, I just want to make sure I'm understanding this correctly :)