2

I have a function something like:

MyClass1 mc1, mc0; //Single Object
MyClass2 mc2; //vector of MyClass1

mc1.Init(1);
mc2.Add(mc1);
mc1 = mc0;

mc1.Init(2);
mc2.Add(mc1);
mc1 = mc0;
//so on......

I actually want to set mc1 = null before at the beginning of the step but cannot do that in C++. So I kept a never-initialized mc0 to do that. Don't think this is an elegant solution. My background was mainly about C# and ASP.NET which is managed.(I think the unmanaged attribute of C++ is the reason why I cannot do object = null. Right?)

hbrls
  • 2,110
  • 5
  • 32
  • 53
  • 2
    For background knowledge read up on the difference between "value semantics" and "reference semantics" and note that in C++ value semantics are often preferred, while they don't exist in C# or Java. As always: Do not try to (unreflectedly) translate and use C# idioms in C++, learn C++ and use the proper idioms. – Fabio Fracassi Jul 12 '11 at 11:34

7 Answers7

8

This has nothing to do with whether the language is managed or not, but rather with C++' different approach to object references. In C#, the declaration MyClass mc; would produce a variable that may refer to a MyClass or be null. In C++, MyClass mc; produces a variable that is a MyClass - the object instance is wholly contained in the variable, and as such, the variable cannot be null. If you want a reference, you would typically use a pointer: MyClass * mc = NULL; or MyClass * mc = new MyClass();.

Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81
  • If I should use `MyClass1 * mc1; *mc1.Init(); mc2.push_back(*mc1); *mc = null;`? And after that, would `what` *mc1 had been pointed to remove itself from memory? – hbrls Jul 13 '11 at 10:29
  • @hbrlovehaku: Based on those questions, I'll strongly advise you to read a C++ book, rather than trying to learn C++ by trying to write C#-like code. Memory management in C++ is _very_ different from in C#, and you _will_ shoot yourself in the foot (repeatedly) if you don't learn it properly. – Aasmund Eldhuset Jul 13 '11 at 10:59
  • @hbrlovehaku: As for the questions themselves: `*` takes precedence over `.`, so when accessing a member through a pointer, you must either write `(*mc1).Init()`, or preferrably `mc1->Init()`. Beware that if you push `*mc1` into a vector, you are inserting a _copy_ of `mc1`; you might want a vector of pointers instead. Also, the object itself cannot be set to `NULL`, but the pointer can: `mc = NULL`. – Aasmund Eldhuset Jul 13 '11 at 11:00
  • I read a simple c++ book in 5 hours. I think that's where problems come from. Thanks for the advice. I will look for more of it. – hbrls Jul 13 '11 at 11:06
  • @hbrlovehaku: I'd go for a book that takes more than 5 hours to read. :-) If you're well versed in other languages, you can concentrate on the parts covering object orientation, constructors, pointers, and memory management. And keep in mind that whenever you have a variable of object type (non-pointer) in C++, such as `MyClass mc1;`, it will behave very differently from what a variable of object type in C# does. – Aasmund Eldhuset Jul 13 '11 at 11:08
2

MyClass *mc1 is a pointer to your class and can be assigned to 0

MyClass mc1 is an istance of your class and since you haven't overloaded the = operator with int you can't assign 0 to it

In C# there are only pointers to classes, so equivalent of C#'s MyClass mc1 in C++ is MyClass *mc1

Djole
  • 1,145
  • 5
  • 10
1

How about this:

mc1 = MyClass();

this is assuming that MyClass has a default constructor.

Guido Domenici
  • 5,146
  • 2
  • 28
  • 38
1

Like everyone else here has said, in C++ you don't and can't simply assign null to an object instance. You can however assign NULL to a pointer to an object. In VS 2010, using the VC 10.0 compiler, you can replace NULL with nullptr instead. The VC 10.0 compiler is a little more strict about usages of both of those. Anyways, that doesn't seem to be what you would need here. In your case, you should have mc1 call some sort of method that will reset it to a known predefined state.

Note: I take it you are trying to avoid the reconstruction of MyClass1 objects? If you are using a std::vector and 'adding' these instances into, then the objects are getting copied all over again, as vector takes copies of what is put inside of it. If you want to speed things up even more, you could keep a vector of pointers to instances of your objects. But that is an entirely new ballgame, and has other consequences too.

C.J.
  • 15,637
  • 9
  • 61
  • 77
1

You don't do it that way in C++. To add objects to a vector you do

std::vector<MyClass1>   mc2;

mc2.push_back(MyClass1(1));
mc2.push_back(MyClass1(2));

There is no need to create intermediate references, or to release them.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • Actually I used `MyClass m1; m1.inita(...); m1.initb(...);mc2.push_back(mc1);` instead of using a `constructor`. Is there some possible style like your suggestion? – hbrls Jul 13 '11 at 10:22
0

In C++ there exists no way to set an object to NULL - you can, on the other hand, set pointers to NULL. Depending on your design goal, you might need to either a) start working with pointers, or b) call mc1.Init(0); (assuming 0 is what you mean by NULL).

EDIT: another answer suggests calling mc1 = MyClass();, which is also a viable option if you don't care what value is contained within mc1 (or you know the default constructor is going to initialise variables in a way such that having a default-constructed variable is an acceptable substitute for NULL

Ben Stott
  • 2,218
  • 17
  • 23
0

In C++, MyClass1 mc1 actually create an object mc1 of type MyClass1. If you want the variable to initially have null value, then you should make mc1 a pointer of type MyClass1 rather than object. Here is a simple example to show you (dont forget that you will be responsible to clean up the object using delete)

MyClass* mc1 = null;
....
mc1 = new MyClass();
mc1->Init(1);
mc2.Add(*mc1); 
// if you are adding object, if your vector hold pointer, then it will be 
// mc2.Add(mc1);
.......
mc1 = null;
Fadrian Sudaman
  • 6,405
  • 21
  • 29