0

I'd like to know if it is poor programming practice to have a class that has a function that only prints output to the screen?

Simple example for understanding purposes: Student class has the usual set and get methods but it also has a function called void PrintStudentDetails();

Should it be done in the main as such:

cout << "Name: " << student.GetName() << endl;

cout << "Age: " << student.GetAge() << endl;

cout << "Gender: " << student.GetGender() << endl;

Or as an object calling the print function in the main as such:

student.PrintStudentDetails();

Please advise me on the proper coding practices.

user4581301
  • 33,082
  • 7
  • 33
  • 54
Jin Yu Chan
  • 19
  • 1
  • 6
  • 1
    For cases like this, you may wish to look into [overloading the I/O operators](https://www.learncpp.com/cpp-tutorial/93-overloading-the-io-operators/). – Brian61354270 Feb 24 '20 at 03:52
  • 1
    If your program is small, that's fine. Something more modular would be to define an overloaded `operator >>` for the class, or to have a function that takes an `ostream&` as in input parameter. Then if you want to change your output stream (use something other than cout) you can – JohnFilleau Feb 24 '20 at 03:52
  • @Brian Thanks for the advice. I am quite fond of the idea of operator overloading but I am unsure about how many different operator overloading functions a class can have. Do you happen to know if there are any limitations? – Jin Yu Chan Feb 24 '20 at 13:32
  • 1
    @JinYuChan There's not limitations that I'm aware of. Overloaded operators are just fancy-named functions. – Brian61354270 Feb 24 '20 at 14:26

1 Answers1

0

Short Version

Overload the insertion operator.

TL;DR Version

While there is nothing harmful about a function that only writes to cout, it is much more useful, and no harder to write, a function that can write to any ostream.

void Student::PrintStudentDetails(std::ostream & out) // pass in any out stream
{
    out << "Name: " << student.GetName() << '\n'
        << "Age: " << student.GetAge() << '\n'
        << "Gender: " << student.GetGender() << '\n';
}

Note: insertion operators can chain.

Side note: std::endl is a new line AND a stream flush, and that stream flush can be very expensive. Generally you only want to flush when you have to to push information immediately to a client or the stream's buffer is full. Prefer to use '\n' to endl in most other cases.

It is only marginally more difficult to write a << overload that prints your class so you can anystream << myClassInstance;.

std::ostream & operator<<(std::ostream & out, // any outstream
                          const Student & student) // the object to print
{
    out << "Name: " << student.GetName() << '\n'
        << "Age: " << student.GetAge() << '\n'
        << "Gender: " << student.GetGender() << '\n';
    return out; // this is the magic that allows chaining
}

You can now

cout << myStudent;

Note: the insertion operator is often implemented as a friend of the class in order to provide easy access to private variables.

For more wisdom on overloading operators read What are the basic rules and idioms for operator overloading?

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • Hi, thanks for the advice. I would like to ask a question about operator overloading. How many instances of operator overloading can one do for a single class? – Jin Yu Chan Feb 24 '20 at 13:30
  • Limited only by the number of operators and sensible permutations of the parameters. – user4581301 Feb 24 '20 at 15:54
  • Assuming the declaration and implementation have already been done for the example below. Does that mean I can have multiple operators as such: os << "Name: " << student.GetName() << endl << "Age: " << student.GetAge(); os2 << "Name: " << student.GetName() << endl << "Age: " << student.GetAge() << endl << "Gender: " << student.GetGender() << endl; – Jin Yu Chan Feb 25 '20 at 01:14
  • @JinYuChan Ahhhh! That's what you meant. Yes. You can effectively chain operators forever. Note: as of the C++17 Standard revision you can even have a computation being output depend on results from a previous computation in the same output. Before C++17 you cannot be assured that all of the operations will be sequenced in order if the compiler figured the program could be more efficient out of order. – user4581301 Feb 25 '20 at 01:23
  • Got it! Thanks for the advice. – Jin Yu Chan Feb 25 '20 at 01:28