C++ 指向类的指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1371608/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:44:04  来源:igfitidea点击:

C++ pointer to class

c++initialization

提问by Zeeshan Rang

Can anyone tell me what the difference is between:

谁能告诉我有什么区别:

Display *disp = new Display();

and

Display *disp;
disp = new Display();

and

Display* disp = new Display();

and

Display* disp(new Display());

采纳答案by Daniel Pryden

The first case:

第一种情况:

Display *disp = new Display();

Does three things:

做三件事:

  1. It creates a new variable disp, with the type Display*, that is, a pointer to an object of type Display, and then
  2. It allocates a new Displayobject on the heap, and
  3. It sets the dispvariable to point to the new Displayobject.
  1. 它创建一个新变量disp,其类型为Display*,即指向类型为 的对象的指针Display,然后
  2. Display在堆上分配一个新对象,并且
  3. 它将disp变量设置为指向新Display对象。

In the second case:

在第二种情况下:

Display *disp; disp = new GzDisplay();

You create a variable dispwith type Display*, and then create an object of a different type, GzDisplay, on the heap, and assign its pointer to the dispvariable.

创建的变量disp类型Display*,然后创建的对象不同的类型GzDisplay,在堆上,和它的指针分配给disp变量。

This will only work if GzDisplay is a subclass of Display. In this case, it looks like an example of polymorphism.

这仅在 GzDisplay 是 Display 的子类时才有效。在这种情况下,它看起来像是polymorphism 的一个例子。

Also, to address your comment, there is no difference between the declarations:

此外,为了解决您的评论,声明之间没有区别:

Display* disp;

and

Display *disp;

However, because of the way C type rules work, there is a difference between:

但是,由于 C 类型规则的工作方式,以下之间存在差异:

Display *disp1;
Display* disp2;

and

Display *disp1, disp2;

Because in that last case disp1is a pointerto a Displayobject, probably allocated on the heap, while disp2is an actual object, probably allocated on the stack. That is, while the pointer is arguably part of the type, the parser will associate it with the variable instead.

因为在后一种情况下disp1指向一个Display对象,可能是在堆上分配的,同时disp2是一个实际的对象,可能是在堆栈上分配。也就是说,虽然指针可以说是类型的一部分,但解析器会将其与变量相关联。

回答by Kirill V. Lyadvinsky

// implicit form
// 1) creates Display instance on the heap (allocates memory and call constructor with no arguments)
// 2) creates disp variable on the stack initialized with pointer to Display's instance
Display *disp = new Display();

// explicit form
// 1) creates Display instance on the heap (allocates memory and call constructor with no arguments)
// 2) creates disp variable on the stack initialized with pointer to Display's instance
Display* disp(new Display());

// 1) creates uninitialized disp variable on the stack
// 2) creates Display instance on the heap (allocates memory and call constructor with no arguments)
// 3) assigns disp with pointer to Display's instance
Display *disp;
disp = new Display();

Difference between explicit and implicit forms of initialization will be seen only for complex types with constructors. For pointer type (Display*) there is no difference.

显式和隐式初始化形式之间的区别仅在具有构造函数的复杂类型中可见。对于指针类型 (Display*),没有区别。

To see the difference between explicit and implicit forms check out the following sample:

要查看显式和隐式形式之间的区别,请查看以下示例:

#include <iostream>

class sss
{
public:
  explicit sss( int ) { std::cout << "int" << std::endl; };
  sss( double ) { std::cout << "double" << std::endl; };
  // Do not write such classes. It is here only for teaching purposes.
};

int main()
{
 sss ddd( 7 ); // prints int
 sss xxx = 7;  // prints double, because constructor with int is not accessible in implicit form

 return 0;
}

回答by Paulius

Display *disp = new Display();

This line of code create a variable of type Display* and initializes it with the address of a newly created object.

这行代码创建了一个 Display* 类型的变量,并使用新创建的对象的地址对其进行初始化。

Display *disp;        // (1)
disp = new Display(); // (2)

First line of code simply declares a variable of type Display*. Depending on your compiler settings - the pointer may or may not be initialized. Basically, it should be treated as an invalid pointer, that doesn't necessary point to NULL.

第一行代码简单地声明了一个 Display* 类型的变量。根据您的编译器设置 - 指针可能会或可能不会被初始化。基本上,它应该被视为一个无效的指针,它没有必要指向 NULL。

Second line assigns address of a newly created object to the pointer.

第二行将新创建的对象的地址分配给指针。

The outcome of both code snippets will be the same.

两个代码片段的结果将是相同的。

With optimizations enabled, any compiler should generate the same assembly for both of them. With optimizations disabled, and with some debug code generation - both snippets might generate totally different code - in the second case, the pointer would first be initialized with a value used by compiler for uninitialized pointers (something like 0xDEADBEEF, or 0xEFEFEFEF - and easily recognizable pattern). In the first snippet - the pointer should always be initialized to the address of the object, regardless of the settings. Note, that this is compiler-dependent - some compilers might do as I say, some may do somthing completely different.

启用优化后,任何编译器都应为它们生成相同的程序集。禁用优化并生成一些调试代码 - 两个片段可能生成完全不同的代码 - 在第二种情况下,指针将首先使用编译器用于未初始化指针的值(例如 0xDEADBEEF 或 0xEFEFEF 之类的值 - 并且易于识别)进行初始化图案)。在第一个片段中 - 无论设置如何,指针都应始终初始化为对象的地址。请注意,这是依赖于编译器的——有些编译器可能会像我说的那样做,有些可能会做一些完全不同的事情。

回答by derobert

You have found four ways to write the same thing.

您已经找到了四种编写相同内容的方法。

Examples 1 (Display *disp…) and 3 (Display* disp…) are identical; the spacing around *does not matter. However, style 1 is often preferred, because:

例1( Display *disp…)和例3( Display* disp…)相同;周围的间距*无关紧要。但是,通常首选样式 1,因为:

Display* disp1, disp2;

actually means:

实际上的意思是:

Display *disp1, disp2;

i.e., disp2 is not a pointer.

即, disp2 不是指针。

Example two (splitting across two lines) has the same effect, and will probably be compiled to the same code. The fourth example, using initializer syntax, does the same thing as well.

示例二(分成两行)具有相同的效果,并且可能会被编译为相同的代码。第四个例子,使用初始化语法,也做同样的事情。

Note that if these were classes, not pointers, there could be a difference in behavior and speed.

请注意,如果这些是类,而不是指针,则行为和速度可能会有所不同。

回答by Motti

One creates an object of type Displayand one of the type GzDisplay, is this on purpose or is it a typo?

创建一个类型的对象Display和一个Gz类型的对象Display,这是故意的还是打字错误?

If it's a typo then there's no difference in regards to the code generated but the first method is preferred since there is no time in which the variable dispis in scope and uninitialized.

如果是拼写错误,则生成的代码没有区别,但首选第一种方法,因为变量没有时间disp在范围内且未初始化。

回答by Victor Sorokin

1) Instance of GzDisplay is created in 2nd variant, whereas in 1st variant, created instance is of Display type (I assume GzDisplay is subclass of Display, right?); 2) Besides that 1st is shorter, in 2nd disp have undefined value until assigned with new GzDisplay(). 2nd variant gives you a chance to accidentally forget that and insert some code that uses disp before it initialized.

1) GzDisplay 的实例是在第二个变体中创建的,而在第一个变体中,创建的实例是 Display 类型(我假设 GzDisplay 是 Display 的子类,对吧?);2) 除了第一个更短之外,在第二个显示中具有未定义的值,直到分配新的 GzDisplay()。第二个变体让您有机会意外忘记它并在初始化之前插入一些使用 disp 的代码。