On 07.11.2016 02:13, JiiPee wrote:
> They say, especially in game programming, that drawing/printing should
> not be done inside the class but some other class should do it (by
> asking the data from the object). Is this the way also with cout?
Yes.
> Say we have:
>
> class Person
> {
> public:
> Person(const string& name, int age, int id) :
> m_name{ name }, m_age{ age }, m_id{ id } {}
> private:
> string m_name;
> int m_age;
> int m_id;
> };
>
> If I want to create a print function which prints all persons details
> what is the best way to do it?
As a non-member.
E.g. this ensures that all the needed information is accessible to
calling code in general.
> First idea/try is obviously somethin like:
>
> class Person
> {
> public:
> Person(const string& name, int age, int id) :
> m_name{ name }, m_age{ age }, m_id{ id } {}
> void print(ostream& os) { os<<m_name<<", " << ....};
In spite of the name this is not a printing function: it's a function
that converts to string.
I think a far better design for this member would be
auto to_string() const
-> string
{ ...
In particular, when the class is used in a GUI the `<string>` header
will likely be included anyway, but not so `<iosfwd>` or `<iostram>`.
Also, standard iostreams are extremely inefficient, possibly due to the
locale stuff that is forced on you, and the modes, both of which makes
robust client code extremely complex in addition to inefficient.
> private:
> string m_name;
> int m_age;
> int m_id;
> };
>
> But now the class is doing two things... printing and holding the data.
> they should be separated, isnt it?
No, it's not printing; it's just converting to string.
This is the #1 litmus test: can you use the class in various GUI frameworks?
If so then it's portable, OK in that respect.
But then, there is the #2 test, can you use the class in different
environments in general?
For example, since you're involving a stream it may be that the code
will depend on an UTF-8 locale having been imbued in that stream. Then
use the code in Windows and there's no such. Uh oh.
> Second idea is to create a non-class
> function which a friend of Person. but any other ideas? Is it best to do
> like in game programming: no printing done in Person class, some other
> function/class asks the values and prints. Obviously we dont want to
> have getters for Person necessary (because it would break OO-idea.).
For conversion to string, try to express that more directly. This is
akin to generally using `++x` instead of `x++`. Don't ask for and
require way more than you actually need for the job.
Well, unless it's money, and the person paying is Donald Trump.
Cheers & hth.,
- Alf