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

时间:2009-11-16 14:54:50

标签: c# c++ pointers

在C#

中创建对象实例时
Myclass mc = new Myclass();

mc现在是对在内存中创建的Myclass对象的引用。它就像是指向那段记忆的“指针”。

与在(托管或非托管)C ++中执行此操作相同或相当:

MyCppClass *mcCppClass = new MyCppClass();

因为这实际上创建了一个指向该类的对象实例的指针。

我只是想弄清楚究竟是什么差异?

6 个答案:

答案 0 :(得分:4)

一个似乎没有人提到的重要区别是:

Myclass mc = new Myclass();

在C#中,这是唯一创建新对象的正确方法。当您需要一个对象时,这就是您创建它的方式。

MyCppClass *mcCppClass = new MyCppClass();

在C ++中,这就是可以创建对象的方式,以及偶尔创建对象的方式。在C ++中使用这种方法的问题是:

    与管理语言相比,
  • new在C / C ++中极其缓慢。如果用于分配你需要的每个对象,那就会受到伤害。
  • 该对象没有固定的生命周期。它在堆上分配,并且在您对其调用delete之前不会销毁它。如果你忘记这样做,它永远不会被破坏。如果您拨打delete两次,您的程序就会崩溃。

在C ++中,您有两种创建对象的方法: 你上面使用的那个:

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

但已修改为包含delete调用,因为没有它,您就会泄漏内存。每当您使用new时,您还必须迟早,致电delete。通常,一个没有另一个是错误。

第二种更常见的方法:

// 2
MyCppClass myobject;

在某些方面,第二个更类似于您的C#示例。它的生命周期由系统自动管理(虽然它的管理方式不同。在C ++中,它持续到它超出范围,在C#中它持续到没有人引用它并且它被垃圾收集 - 但在这两种情况下,你不必做任何事情来确保它被销毁)。通常,它也是正确的方式来创建对象实例,原因相同。

新C ++程序员最常犯的错误之一是使用new分配每个对象,存储指向它们的指针,然后尝试以记住删除它们。一个更简单,更健壮,更有效的解决方案是避免new并尽可能避免指针。有时,您需要一个其生命周期不限于声明范围的对象(并且复制对象不是在该范围之外使用它的选项)。然后使用new,并且很可能将结果指针包装在某种类型的智能指针中。

答案 1 :(得分:0)

在C ++中,您负责删除该内存,而在C#中则不是。这可能是你想要记住的最大差异。

就相似之处而言,它们都是堆分配的对象。

Here是关于C#中堆与堆栈的好文章,您可能会发现它很有用。

答案 2 :(得分:0)

它们在new为成员变量分配内存的意义上是相等的。它们的不同之处在于C ++(在您的示例中)是指向内存中对象的指针,并且C#具有引用(它不是指针,也不是C ++引用,即它可以为null)。

两种语言都保证new的结果为非空,或抛出错误(即C#中的OutOfMemoryException)。

当然,对象,类等的整个行为在C ++和C#(垃圾收集,自动装箱行为,静态构造函数等)中是完全不同的。

编辑:其他答案中没有提到的一件事:C ++中的任何new都会调用类的完整层次结构的构造函数。 C#只是单继承,只会调用层次结构中的第一个构造函数或对象ctor。在C#中,如果没有定义构造函数,new X()等于new object()

答案 3 :(得分:0)

它们很相似,但C#版本有一些重要的注意事项:

  • 使用新的Blah()创建值和引用对象。值对象的行为与引用对象不同:分配它们会复制数据,而不是引用。

  • C#引用对象是垃圾回收

答案 4 :(得分:0)

我认为在这个例子中,C#版本与reference更加相似:

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

在C ++中,您不必担心reference指向null,就像它一样。它就在那里,所以你使用它。但是,在C#中,对象引用可以为空。

另外,正如@Kyle Walsh指出的那样,你负责删除与C ++中mcCppClass指针相关的内存。在C#中,您的对象将自动进行垃圾回收。

需要注意的一点是C#区分了类和结构。类是引用类型,而结构是值类型。在C ++中,类和结构仅在默认成员可见性级别上不同(默认情况下,类具有私有成员可见性,而默认情况下结构具有公共成员可见性)。如果从C ++转移到C#,这是一个重要的区别。有关详细信息,请参阅here

答案 5 :(得分:0)

它可能被称为引用,但它被作为指针处理(它可以是NULL)。在C ++中,引用不能为null,它总是引用相同的实例。

在C ++中,引用和指针之间存在很大差异。而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

在C ++中,您不需要在免费商店中分配您的实例(«使用新»)。您也可以在堆栈中声明它们。在后一种情况下,您不必担心删除它们。