在C#
中创建对象实例时Myclass mc = new Myclass();
此mc
现在是对在内存中创建的Myclass
对象的引用。它就像是指向那段记忆的“指针”。
与在(托管或非托管)C ++中执行此操作相同或相当:
MyCppClass *mcCppClass = new MyCppClass();
因为这实际上创建了一个指向该类的对象实例的指针。
我只是想弄清楚究竟是什么差异?
答案 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)
答案 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 ++中,您不需要在免费商店中分配您的实例(«使用新»)。您也可以在堆栈中声明它们。在后一种情况下,您不必担心删除它们。