使用和不使用new运算符初始化对象

Aan*_*Aan 22 c++ memory-management new-operator

如果我有课 Rectangle

class Rectangle{

private:
    double width;
    double height;


public:
void    Set(double w , double l){
    width   = w;
    height  = l;
}
};
Run Code Online (Sandbox Code Playgroud)

我发现了一个这样的对象:

Rectangle *Obj;
Run Code Online (Sandbox Code Playgroud)

然后尝试初始化其属性:

Obj->Set(3,5);
Run Code Online (Sandbox Code Playgroud)

编译器在运行时显示: The variable 'Obj' is being used without being initialized.

问题可以通过以下方式解决:

Rectangle *Obj=new Rectangle;
Run Code Online (Sandbox Code Playgroud)

我会问一下原因!为什么编译器在编译时没有显示任何错误?

arn*_*rne 24

Rectangle *Obj;
Run Code Online (Sandbox Code Playgroud)

只定义一个指向类对象的指针Rectangle.定义指针不会为对象本身保留任何内存,仅用于指针.因此,如果您访问指针,您可能最终会在内存中甚至不属于您的进程的地址.但是,编译器无法知道您尚未初始化指针(此处的关键字是别名),因此无法输出错误消息.

解决方案要么new像您建议的那样使用,要么声明一个Rectangle类似的实例:

Rectangle Obj;
Run Code Online (Sandbox Code Playgroud)

这将调用默认构造函数.然后,您可以使用设置成员

Obj.Set(3, 5);
Run Code Online (Sandbox Code Playgroud)

  • 只是一个尼特,但是`Rectangle*Obj;`不仅仅是_declare_; 它_defines_也是.它确实保留了记忆; 足够的内存来存储指针. (8认同)

Bjö*_*lex 8

我发现了一个这样的对象:

Rectangle *Obj;
Run Code Online (Sandbox Code Playgroud)

错了,这声明了一个指针,而不是一个对象.必须使用new或通过为指针指定现有对象的地址来初始化指针.

  • 指针是一个对象,至少在C++中是这样.这定义了一个类型为`Rectangle*`的对象.当然,未初始化. (4认同)

seh*_*ehe 5

嗯,有点混乱:

编译器在运行时显示:变量“Obj”正在使用但未初始化

这就是您所说的编译时间。只是理顺行话。

另外,最简单的方法是

Rectangle Obj;
Obj.Set(3,5);
Run Code Online (Sandbox Code Playgroud)

这对于大多数场景来说已经足够了,动态分配或多态容器除外:

std::vector<Shape*> v;
v.push_back(new Rectange());
v.back()->Set(3,5);

v.push_back(new Circle());
v.back()->Set(3,5);

//
Run Code Online (Sandbox Code Playgroud)

但无论何时使用,newdelete您也应该记住。这可能是一场噩梦(也有例外)。我建议:

std::vector<std::shared_ptr<Shape*> > v;
v.push_back(std::make_shared<Rectange>());
v.back()->Set(3,5);

v.push_back(std::make_shared<Circle>());
v.back()->Set(3,5);
Run Code Online (Sandbox Code Playgroud)

  • 最简单(也是最好)的方法不是:“矩形 Obj = { 3, 5 };”。作为一般规则,您不应创建未初始化的对象。(唯一的例外可能是如果您在下一个语句中使用“&gt;&gt;”来阅读它。) (2认同)
  • 它与他的“矩形”实现有关。我错过了“私人”;无法创建初始化的“矩形”。他需要一个构造函数,而不是“Set”函数。 (2认同)