problem with adding number to variable when overloading a operator

#include <iostream>

using namespace std;

class MY_OBJECT
{
public:
int x, y, w, h;
};

class MY_ROOM
{
public:
MY_OBJECT *objects[];
int objNum = 0;
};


MY_ROOM& operator>> (MY_ROOM &__room, MY_OBJECT &__object)
{
__room.objects[__room.objNum] = &__object;
__room.objNum += 1;
}

int main()
{
MY_OBJECT door, roof, wall, floor, desk;
MY_ROOM bedroom;
cout << bedroom.objNum << endl; //returns 0
bedroom >> wall; //what happens here that cause me problem?
cout << bedroom.objNum; // returns a wrong number instead of 1
return 0;
}
Last edited on
There are a number of problems here. First, you can't declare MY_OBJECT* objects[] inside a class. This is an array of indeterminate size, so C++ can't know how large the type MY_ROOM is. There is a trick that allows you to put this as the last member variable of the class, but you don't want this right now. What you really want is a std::vector.

Your type names are strange. Just call them Room and Object.

Next, your operator>> usage is backwards. When used in the cout style, this operator means "put to" or "take from." What bedroom >> wall means in this idiom is "take something from bedroom and put it in wall." Instead, you want bedroom << wall, or "take wall and put it in bedroom, so just switch that operator around. Oh, and don't use __variables like that, there's no point and it just adds noise to the function. And one more thing, if it needs to be able to access member variables, it should be a member function.

But now onto the meat of your function. Firstly, even if you had an empty array as you tried to declare, it's empty. There is no memory allocated for it. You can't just grow an array like that and you're trying to dynamically grow an array by assigning to it. This will overwrite adjacent data and/or crash your program. However, if you use std::vector, all you need to do is call push_back.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <vector>

class Object {
public:
   int x, y, w, h;
};

class Room {
   std::vector<Object*> objects;
public:

   Room& operator<<(Object &object) {
      objects.push_back(&object);
      return *this;
   }

   auto num_objects() {
      return objects.size();
   }
};

int main() {
   Object door, roof, wall, floor, desk;
   Room bedroom;

   std::cout << bedroom.num_objects() << std::endl;
   bedroom << door << roof << wall << floor << desk;
   std::cout << bedroom.num_objects() << std::endl;

   return 0;
}
When you see << or >> in the context of a stream, the arrow points in the direction the data flows.
For instance:
1
2
3
4
std::cin >> x;
// data flows from the input stream into x
std::cout << x;
// data flows from x into the output stream 


If I had to guess, you've been reading Microsoft's implementation. While you're free (I suppose) to keep your type names in ALL_CAPS, your variable names must be changed. It is illegal to declare names which contain more than one consecutive underscore, or names which begin with an underscore followed by a capital letter. It's not merely noisy, but undefined behavior.

In the global namespace, you're also prohibited from declaring names that begin with an underscore.

It's just not worth it to break that rule - change your variable names. If you really need a reminder that you're working with a member variable, just use one underscore.

IMO it's a good idea (but not required) to restrict ALL_CAPS_NAMES to macros only, because macros have unpredictable and idiosyncratic semantics, and must be treated carefully. For this reason, it's important to know what's a macro and what's not.
Topic archived. No new replies allowed.