简体   繁体   English

C#对象和C ++对象的区别

[英]C# objects and C++ objects, the difference

When creating an object instance as such in C# 在C#中创建对象实例时

Myclass mc = new Myclass();

This mc is now a reference to a Myclass object created in memory. 现在,此mc是对在内存中创建的Myclass对象的引用。 It's like a 'pointer' to that memory. 这就像是该内存的“指针”。

Is it the same or comparable to doing this in (Managed or Unmanaged) C++: 与在(托管或非托管)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? 我只是想找出差异到底是什么?

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. 在C#中,这是创建新对象的唯一正确方法。 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. 在C ++中,这是你可以创建一个对象,你如何偶尔需要创建一个对象。 The problem with using this approach in C++ is that: 在C ++中使用这种方法的问题是:

  • new is extremely slow in C/C++, compared to a managed language. 与托管语言相比, new在C / C ++中非常慢。 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. 它是在堆上分配的,直到您对其调用delete之前,它不会被销毁。 If you forget to do so, it is never destroyed. 如果您忘记这样做,它永远不会被破坏。 If you call delete twice, your program blows up. 如果您两次调用delete ,则程序会崩溃。

In C++, you have two ways to create objects: The one you used above: 在C ++中,有两种创建对象的方式:上面使用的一种:

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

but modified to include the delete call as well, because without it, you're leaking memory. 但已修改为也包括delete调用,因为没有它,您将泄漏内存。 Whenever you use new , you must also, sooner or later, call delete . 每当您使用new ,还必须迟早致电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. 在某些方面,第二个示例与您的C#示例更相似。 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). 它的生存期由系统自动管理(尽管管理的方式有所不同。在C ++中,它一直持续到超出范围为止;在C#中,它一直持续到没有人引用它并得到垃圾回收为止-但在两种情况下,则无需执行任何操作即可确保它被销毁)。 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. 新C ++程序员最常见的错误之一是使用new分配每个对象,存储指向它们的指针,然后尝试记住删除它们。 A simpler, more robust and more efficent solution is to avoid new and avoid pointers as far as possible. 一个更简单,更可靠,更有效的解决方案是避免new并尽可能避免使用指针。 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. 然后,使用new ,并且很可能将结果指针包装在某种类型的智能指针中。

In C++ you are responsible for deleting that memory, whereas in C# you are not. 在C ++中,您负责删除该内存,而在C#中则不负责。 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. 是一篇有关C#中的堆vs堆栈的好文章,您可能会发现它很有用。

They are equal in the sense that both new allocates memory for the member variables. 从两个new为成员变量分配内存的意义上说,它们是相等的。 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, ie, it can be null). 它们的不同之处在于,C ++(在您的示例中)是指向内存中对象的指针,而C#具有引用(它既不是指针,也不是C ++引用,即它可以为null)。

Both languages guarantee the result of new to be non-null, or throw an error (ie an OutOfMemoryException in C#). 两种语言都保证new的结果为非null或抛出错误(即C#中的OutOfMemoryException )。

Of course, the whole behavior of objects, classes etc is quite different in C++ and C# (garbage collection, auto-boxing behavior, static constructor etc). 当然,在C ++和C#中,对象,类等的整体行为是完全不同的(垃圾回收,自动装箱行为,静态构造函数等)。

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 ++中的任何new都将调用类的完整层次结构的构造函数。 C# is single-inheritance only and will only call the first constructor in the hierarchy or the object ctor. C# 仅是单继承 ,只会调用层次结构中的第一个构造函数或对象ctor。 In C#, if no constructors are defined, new X() is equal to new object() . 在C#中,如果未定义构造函数,则new X()等于new object()

They are similar, but there are some important caveats with the C# version: 它们相似,但是C#版本有一些重要警告:

  • You create both value and reference objects with new Blah(). 您可以使用新的Blah()创建值和引用对象。 Value objects don't behave like reference objects: assigning them copies the data, not the reference. 值对象的行为不像引用对象:为其分配值将复制数据,而不是引用。

  • C# reference objects are garbage collected C#参考对象被垃圾收集

I think the C# version is more analagous to reference in this example: 我认为在此示例中,C#版本更不适合reference

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

In C++, you don't have to worry about reference pointing to null, as it were. 在C ++中,您不必担心指向null的reference It's just there, so you use it. 它就在那里,所以您可以使用它。 In C#, though, the object reference can be null. 但是,在C#中,对象引用可以为null。

Also, as @Kyle Walsh pointed out, you are responsible for deleting the memory associated with the mcCppClass pointer in C++. 另外,正如@Kyle Walsh指出的那样,您负责删除与C ++中的mcCppClass指针关联的内存。 In C#, your object will be garbage collected automatically. 在C#中,将自动垃圾回收您的对象。

One thing to be aware of is that C# makes a distinction between classes and structs. 要注意的一件事是C#区分了类和结构。 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). 在C ++中,类和结构的默认成员可见性级别不同(类默认具有私有成员可见性,而结构默认具有公共成员可见性)。 This is an important distinction to note if moving from C++ to C#. 如果从C ++迁移到C#,这是要注意的重要区别。 See here for more details. 有关更多详细信息,请参见此处

It might be called a reference, but it's handled as a pointer (it can be NULL). 它可能被称为引用,但它被作为指针处理(可以为NULL)。 In C++ a reference can't be null, it always refer to the same instance. 在C ++中,引用不能为null,它始终引用同一实例。

In C++, there is a strong difference between references and pointers. 在C ++中,引用和指针之间有很大的区别。 And C# (or java's) "references" are closer to C++ pointers than to C++ references. C#(或Java)的“引用”比C ++引用更接近C ++指针。

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 »). 在C ++中,您不需要在免费存储区中分配实例(“使用新的»”)。 You can also declare them on the stack. 您也可以在堆栈上声明它们。 In the later case, you don't have to worry about deleting them. 在后一种情况下,您不必担心将其删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM