【问题标题】:C++ pointer to class指向类的 C++ 指针
【发布时间】:2009-09-03 05:51:18
【问题描述】:

谁能告诉我两者之间有什么区别:

Display *disp = new Display();

和

Display *disp;
disp = new Display();

和

Display* disp = new Display();

和

Display* disp(new Display());

【问题讨论】:

  • 但是为什么第一种情况是“new Display”而第二种情况是“new GzDisplay”呢?
  • “Display* disp = new Display();”也有区别
  • 不,你的问题不是“臭”。继续问您的问题,我们将继续回答。 :)

标签: c++ initialization


【解决方案1】:

第一种情况:

Display *disp = new Display();

做三件事:

  1. 它创建一个新变量disp,类型为Display*,即指向Display类型对象的指针,然后
  2. 它在堆上分配一个新的Display对象,并且
  3. 它将disp 变量设置为指向新的Display 对象。

第二种情况:

Display *disp; disp = new GzDisplay();

您创建一个类型为Display* 的变量disp,然后在堆上创建一个不同类型的对象GzDisplay,并将其指针分配给disp变量。

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

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

Display* disp;

和

Display *disp;

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

Display *disp1;
Display* disp2;

和

Display *disp1, disp2;

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

【讨论】:

  • 他改变了问题。 GzDisplay 不再存在。
  • @Daniel:我觉得你很困惑; SO 只显示最近编辑的作者;您必须单击“17 分钟前”(或显示的任何时间)以查看所有修订,以及谁进行了修订。当你这样做时,你会发现原来的海报改变了问题。如果您觉得 UI 令人困惑,请在 meta.stackoverflow.com 上发表评论。
  • @derobert:我很抱歉。我已经删除了我的 cmets。
【解决方案2】:
// 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();

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

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

#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;
}

【讨论】:

    【解决方案3】:
    Display *disp = new Display();
    

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

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

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

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

    两个代码 sn-ps 的结果是一样的。

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

    【讨论】:

      【解决方案4】:

      你已经找到了四种写相同东西的方法。

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

      Display* disp1, disp2;
      

      其实意思是:

      Display *disp1, disp2;
      

      即 disp2 不是指针。

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

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

      【讨论】:

      • @Daniel:我没有这样做。 stackoverflow.com/revisions/1371608/list,修订版 4,显示 OP 更改了他自己的问题。我刚刚为他修复了他的格式。
      • @derobert:撤回,我很抱歉。由于我还没有足够的代表来编辑其他人的问题,所以我不知道如何搜索问题的先前版本。我也删除了我的反对票。
      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-12
          • 2018-03-24
          • 2021-12-31
          • 1970-01-01
          • 2021-01-12
          • 2010-09-08
          相关资源
          最近更新 更多