为什么我需要在 C# 中实例化对象,而不是在 C++ 中实例化对象才能访问类的函数?

Why do I need to instantiate an object in C#, but not in C++ in order to access a class's functions?

本文关键字:实例化 对象 访问 函数 C++ 为什么      更新时间:2023-10-16

我最近开始用C#进行Unity(游戏引擎)开发编程。我注意到,与C++不同;C#要求我在使用堆上的成员函数或变量之前先实例化对象。其中,与C++一样,我可以声明一个对象并从声明名称调用任何函数。

C++示例:

#include <iostream>
using namespace std;
class SampleClass 
{
   void PrintFunc()
   {
      cout<<"Hello World"<<endl;
   }
 }
int main()
{
   SampleClass objectC; //Object declaration
   objectC.PrintFunc(); //Use of function without instantiation
   //The above code will print'Hello World'
}

C#示例:

 using System
 namespace ConsoleProject2
{
    class MainClass
   {
   class SampleClass
   {
        Void PrintFunc()
        {
          Console.WriteLine("Hello World");
        }
    }
    public static void Main (string[] args)
    {
        SampleClass objectC = new SampleClass();
        //Must instantiate before accessing member functions 
        objectC.PrintFunc(); //Prints out 'Hello World'
    }
}

}

在Unity的自动内存管理网站上阅读时,我只能得出结论,由于它是自动垃圾收集的,它可能需要你在堆上放置新对象,因为它会为你释放它们。(可能是错误的假设,请纠正我)

为什么这两种语言在访问对象属性时有所不同?是C++中的对象被放置在堆栈上,因为没有实例化;如果是,为什么不将所有对象都放在堆栈上?

谢谢。

互联网上流传着很多关于这个话题的错误信息,所以请仔细阅读。

我注意到,与C++不同,C#要求我在使用其成员函数或变量之前先实例化堆上的对象。

在C#中这样想是错误的。不要把"新"看作是"堆上存储的东西"。把"new"想象成"调用初始化对象的构造函数的东西"。无论是通过复制该对象(一种值类型)来传递该对象,还是通过自动取消引用对其的引用(一种引用类型)来访问该对象,都不会改变这样一个事实,即每个对象都需要以确保其正确初始化的方式构建,无论它是在长期存储中还是在短期存储中。

C++中的对象是否被放置在堆栈上,因为没有实例化

有一个实例化,你只是没有看到它,因为它在代码中没有表现出来。将为您调用一个默认构造函数。

如果是,为什么不将所有对象都放在堆栈上?

停止思考"堆栈"answers"堆",开始思考"短期变量"answers"长期变量"。为什么我们不将所有对象都放在短期变量池中因为有些物体的寿命很长,这就是为什么。

放松,让垃圾收集器完成它的工作。它做得很好!

在CLR中,对象默认在堆上创建。

https://msdn.microsoft.com/en-us/library/f144e03t(v=vs.110).aspx

有一些方法可以在堆栈上创建对象,但通常所有内容都是在堆上创建的。

在C++中,使用new在堆上创建对象,而Object o;在堆栈上创建对象。

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx

C++和C#在值类型的行为上没有区别(从C#的角度来看,C++类是什么)。

以下C#代码编译并运行良好,代码与C++版本相同:

public static void Main (string[] args)
{
  SampleClass objectC; // variable declaration, initialized with default of type
  objectC.PrintFunc(); //Use of function of object just initialized
}

struct SampleClass // note: "struct" in C# matches C++ "class"/"struct"
{
     public void PrintFunc()
    {
      Console.WriteLine("Hello World");
    }
}

反之亦然:C++中的指针大致相当于C#中的类,下面的C++代码将不起作用:

int main()
{
   SampleClass* objectC; // "SampleClass*" in C++ is equivalent 
                         // of variable of class type in C# 
   objectC->PrintFunc(); //try to use of function without instantiation
   //The above code will NRE
}

*语言和平台确实非常不同,但将C#类与C++类进行比较是试图将对一种语言中概念的理解应用于另一种语言的错误方法。

堆与堆的详细解释是Eric Lippert的真实答案。。。

在C++中,编写SomeClass objectName;会调用默认构造函数来初始化对象。一般来说,C++中没有未初始化的类类型值。