tags:

views:

197

answers:

6

When creating an object instance as such in C#

Myclass mc = new Myclass();

This mc is now a reference to a Myclass object created in memory. It's like a 'pointer' to that memory.

Is it the same or comparable to doing this in (Managed or Unmanaged) C++:

MyCppClass *mcCppClass = new MyCppClass();

Because this actually creates a pointer to an object instance of the class.

I'm just trying to find out what exactly the differences are?

A: 

In C++ you are responsible for deleting that memory, whereas in C# you are not. That's probably the biggest difference you'll want to remember.

As far as the similarities, they are both heap-allocated objects.

Here is a good article on heap vs stack in C# which you might find useful.

Kyle Walsh
A: 

They are equal in the sense that both new allocates memory for the member variables. They are different in that C++ (in your example) is a pointer to the object in memory and that C# has a reference (which is not a pointer, but not a C++ reference either, i.e., it can be null).

Both languages guarantee the result of new to be non-null, or throw an error (i.e. an OutOfMemoryException in C#).

Of course, the whole behavior of objects, classes etc is quite different in C++ and C# (garbage collection, auto-boxing behavior, static constructor etc).

EDIT: One thing not mentioned in the other answers yet: any new in C++ will call the constructor of the full hierarchy of classes. C# is single-inheritance only and will only call the first constructor in the hierarchy or the object ctor. In C#, if no constructors are defined, new X() is equal to new object().

Abel
A: 

They are similar, but there are some important caveats with the C# version:

  • You create both value and reference objects with new Blah(). Value objects don't behave like reference objects: assigning them copies the data, not the reference.

  • C# reference objects are garbage collected

Eric
A: 

I think the C# version is more analagous to reference in this example:

MyCppClass *mcCppClass = new McCppClass();
MyCppClass &reference = *mcCppClass;

In C++, you don't have to worry about reference pointing to null, as it were. It's just there, so you use it. In C#, though, the object reference can be null.

Also, as @Kyle Walsh pointed out, you are responsible for deleting the memory associated with the mcCppClass pointer in C++. In C#, your object will be garbage collected automatically.

One thing to be aware of is that C# makes a distinction between classes and structs. Classes are reference types, while structs are value types. In C++, classes and structs only differ in their default member visibility level (classes have private member visibility by default while structs have public member visibility by default). This is an important distinction to note if moving from C++ to C#. See here for more details.

Matt Davis
I agree to the similarity with references, and as you said, references cannot be null in C++. However, they *can* be null in C# ;-)
Abel
Yep. Missed that. Correcting the post now...
Matt Davis
C# references are allowed to be `null`, whereas C++ references are not. Also C# references ensure that their targets will have a lifetime at least as long as every reference to it, whereas C++ references do not. They actually have very little in common. Just about the only common thing is that they can be used without special de-referencing syntax, and so use dot to access members.
Daniel Earwicker
A: 

It might be called a reference, but it's handled as a pointer (it can be NULL). In C++ a reference can't be null, it always refer to the same instance.

In C++, there is a strong difference between references and pointers. And C# (or java's) "references" are closer to C++ pointers than to C++ references.

int a = 3;
int b = 2;
int & c = b; // c and b will alway refer to the same thing.
c = a;    
std::cout << b << std::endl; // shows 3

int * pa = new int(3);
int * pb = new int(2);
int * pc = pb;
pc = pb; // pc and pb are now refering to different things

std::cout << *pb << std::endl;// shows 2

In C++, you don't need to alloc your instances in the free store (« using new »). You can also declare them on the stack. In the later case, you don't have to worry about deleting them.

Tristram Gräbener
+4  A: 

An important difference, which no one seems to have mentioned yet, is this:

Myclass mc = new Myclass();

in C#, this is the only correct way to create a new object. When you need an object, this is how you create it.

MyCppClass *mcCppClass = new MyCppClass();

In C++, this is how you can create an object, and how you occasionally have to create an object. The problem with using this approach in C++ is that:

  • new is extremely slow in C/C++, compared to a managed language. If used to allocate every object you need, it's going to hurt.
  • The object has no fixed lifetime. It is allocated on the heap, and it is not destroyed until you call delete on it. If you forget to do so, it is never destroyed. If you call delete twice, your program blows up.

In C++, you have two ways to create objects: The one you used above:

// 1
MyCppClass *myobject = new MyCppClass();
delete myobject;

but modified to include the delete call as well, because without it, you're leaking memory. Whenever you use new, you must also, sooner or later, call delete. One without the other is, in general, an error.

And the second, more common, approach:

// 2
MyCppClass myobject;

The second one is, in some ways, more similar to your C# example. Its lifetime is automatically managed by the system (although the way it is managed is different. In C++, it lasts until it goes out of scope, where in C# it lasts until no one references it and it gets garbage collected - but in both cases, you don't have to do anything to ensure it is destroyed). It is also, in general, the correct way to create object instances, for the same reason.

One of the most common mistakes made by new C++ programmers is to use new to allocate every object, store pointers to them, and then try to remember to delete them. A simpler, more robust and more efficent solution is to avoid new and avoid pointers as far as possible. Occasionally, you need an object whose lifetime is not limited to the declaring scope, (and where copying the object isn't an option for using it outside that scope). Then you use new, and most likely, wrap the resulting pointer in a smart pointer of some type.

jalf
A simple technique for new C++ programmers is to use smart pointers instead of raw pointers. Just making every pointer into a `std::tr1::shared_ptr<>` will solve a whole lot of problems. It isn't the right thing to do all the time, but it'll work well enough and is an easy rule to remember.
David Thornley
I would rather mention that the C# pointer is more like a boost::shared_ptr in C++. That would give it the same use semantics in both languages. It is unfair to think of objects in the two languages being the same (semantically they look the same) but there is a lot of extra compiler work happening on the C# object that is not done on the C++ pointer.
Martin York
I disagree that stack allocation is more common with custom objects than heap allocation is. Also, you skipped over the difference between reference and value types. 'a = b' has very different meaning in C# depending on whether a and b are reference or value types.
Eric
On the first part, you are (or should be) wrong. Among C++ programmers *who know what they're doing*, heap allocation is rare. When it happens it is typically wrapped inside a stack-allocated RAII object -- as `std::vector` does. You're right that I skipped over .NET's value types. The reason is that they're *mostly* irrelevant to this answer. They don't exactly fit what I said about lifetime lasting until the object gets GC'ed, but the semantics of `a = b` has nothing to do with this answer, so I don't see why I should have mentioned that.
jalf
The semantics of `a = b` is relevant because Tony states "Because this actually creates a pointer to an object instance of the class." This implies he does not yet understand the difference between reference and value types.
Eric