2

For this example im gonna just use two nonsense class objects - X and Y. Really all that matters though is X.

X contains several member functions: an array of Y pointers, and a title that names an object of type X.

During construction, the only thing needed is the name of the class object. ergo, its declared like

X newList("ListTitle")

Now, logically, you'd think that the way to add data to the array of pointers would be something along the lines of

for(int x = 0; each item passed){
 newList.Array[x] = itemPassed[x]; 

However, I've seen assignments that want us to do this in a kind of bizarre way. we're being asked to overload '<<' so that it somehow would initialize the array of pointers by writing

newList <<"Item 1"<<"item 2"<<"item3";

Is this method of adding things to members of a class a legitimately used thing in an actual job scenario? When im looking at it, it doesn't seem syntactically right and pretty damn unneeded. Im just trying to figure out if this is something i'd ever actually use outside of school classes.

MonocleHat
  • 43
  • 6

4 Answers4

2

Is this method of adding things to members of a class a legitimately used thing in an actual job scenario? When im looking at it, it doesn't seem syntactically right and pretty damn unneeded. Im just trying to figure out if this is something i'd ever actually use outside of school classes.

Some of C++s power stems from the possibility to overload operators. As always with great power comes great responsibility. Operators can be overloaded to do the obvious, for example nobody would be surprised by code like this

Matrix a{ {1,2},{2,3} };
Matrix c = a + a;

Maybe you don't even notice that + here is a custom operator. C++ by itself cannot add two matrices. One downside of operator overloading is that you can overload them to do basically anything and sometimes it isnt that obvious. The line between a good operator overload and one that leads to confusing code is thin.

Concerning your concrete example, it is a pattern that you can also find elsewhere. Eigen is a well known algebra library. An example from their documentation is:

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
  Matrix2d a;
  a << 1, 2,
       3, 4;
  MatrixXd b(2,2);
  b << 2, 3,
       1, 4;
  std::cout << "a + b =\n" << a + b << std::endl;
  std::cout << "a - b =\n" << a - b << std::endl;
  std::cout << "Doing a += b;" << std::endl;
  a += b;
  std::cout << "Now a =\n" << a << std::endl;
  Vector3d v(1,2,3);
  Vector3d w(1,0,0);
  std::cout << "-v + w - v =\n" << -v + w - v << std::endl;
}

Note the use of the << operator to set the matrix elements. They add some comma operator voodoo, but the use of the << operator is rather similar to what you are supposed to implement.

Is this method of adding things to members of a class a legitimately used thing in an actual job scenario?

Yes. Using the operator<< to "insert" elements into an object is perfectly legitimate. You will see such uses of operator overloading in various libraries. If an operator is used in such a way of course it requires proper documentation, because knowing the C++ language is not sufficient to know what an operator actually means in a certain context.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
1

You can make a function to add new Y objects to X array. Every time the function is called it returns the same x object so the function can be called again with the same x.

X& operator<<(X& x, const char * s){
  x.Array.push_back(new Y(s));
  return x;
}

(push_back is how you'd add an item with std::vector, or emplace_back)

This is similar to how std::cout works.

QuentinUK
  • 2,997
  • 21
  • 20
  • that actually seems like a pretty feasible way to implement it I really appreciate that clarification here. Cause it just doesnt seem right to be using << for assigning things so it seemed rather confusing (i wish i could accept two answers honestly, the one i accepted for explaining potential uses for it, and this one for actually showing a proper implementation for it) – MonocleHat Mar 09 '20 at 19:43
1

Is this method of adding things to members of a class a legitimately used thing in an actual job scenario?

Probably not. Not in most cases anyway.

Queues and stacks might find a use for it, where << means add to the queue or stack, and >> means read and remove from the queue or stack.

Other possible uses is if you find a reason to write your own stream, you could store data as a std::vector and use the << operator to add character data to it.

In general, however, I wouldn't recommend using the << operator to do stuff like this. It's too easily confused with std::ostream's and std::istream's << and >> operators. Most people reading your code could easily misunderstand it. Plus, there are better ways to initialize data anyway, such as initializer lists.

0

Technically it is perfectly feasible to work like you intend to and Quentin’s answer explains how to do it.

It is furthermore common practice to use operator<< as stream inserter for output of data (to console, a file, but also in memory in the case of stringstreams). But with a stream like interface, your users could legitimately expect that you implement stream behaviors consistently, so that they could use some formatting options such as setw or even endl.

But this stream-like usage is an exception and not the rule. It does not correspond to the usual semantic of the shift operator << that is not expected to have any side effects on its operands. Therefore, unless X represents some kind of streams, I would advise against it and recommend to use instead the technique of method chaining:

X.push(Y1).push(Y2).push(Y3); 

You would define push() (or append or add) exactly as Quentin proposed operator<<, except for the name of the function.

Christophe
  • 68,716
  • 7
  • 72
  • 138
  • 1
    Yeah I'm more used to using it as a stream inserter for data, not for assigning things into an object. X doesnt represent a stream, in this case its a class, and we're using it to assign data into a member array. so its weird to see it used for anything but output of data – MonocleHat Mar 09 '20 at 19:40