简体   繁体   English

为什么有些人将对象定义为指针?

[英]Why do some people define objects as pointers?

I'm currently learning C++ and I can't wrap my head around why one would define an object of a class as a pointer (ie Car *c = new Car; as opposed to Car c; ) for no apparent reason?我目前正在学习 C++,我无法理解为什么有人会无缘无故地将 class 的 object 定义为指针(即Car *c = new Car;而不是Car c; )?

Take for example:举个例子:

#include <iostream>

class Car {
   public:
   void accelerate() { std::cout << "Accelerating!.\n"; }
};

int main() {
   Car *c = new Car;

   c->accelerate();

   return 0;
}

Why would one do it like that when it is much more intuitive to do it like this:当这样做更直观时,为什么要这样做:

#include <iostream>

class Car {
   public:
   void accelerate() { std::cout << "Accelerating!.\n"; }
};

int main() {
   Car c;

   c.accelerate();

   return 0;
}

If a pointer to the object is ever needed, one could always declare one, no?如果需要指向 object 的指针,总是可以声明一个,不是吗?

why one would define an object of a class as a pointer为什么要将 class 的 object 定义为指针

One shouldn't.一个不应该。 Pointers are generally to be avoided as much as possible.通常要尽可能避免使用指针。 However, they are necessary when you are doing polymorphism.但是,当您进行多态性时,它们是必需的。 In that case, use the smart pointers shared_ptr , unique_ptr instead of a raw pointer.在这种情况下,使用智能指针shared_ptrunique_ptr而不是原始指针。

The following is a bad example of using pointers because now you have one additional problem ie, "freeing the allocated memory".下面是一个使用指针的坏例子,因为现在你有一个额外的问题,即“释放分配的内存”。

int main() {
   Car *c = new Car;
   c->accelerate();
   return 0;
}

And you are right, the second example is much better and should be the default way to go.你是对的,第二个例子要好得多,应该是 go 的默认方式。

Whenever such questions occur, it is best to see what C++ Core Guidelines say:每当出现此类问题时,最好看看C++ Core Guidelines是怎么说的:

R.11: Avoid calling new and delete explicitly R.11:避免显式调用 new 和 delete

Reason原因

The pointer returned by new should belong to a resource handle (that can call delete). new 返回的指针应该属于资源句柄(可以调用 delete)。 If the pointer returned by new is assigned to a plain/naked pointer, the object can be leaked.如果将 new 返回的指针分配给普通/裸指针,则 object 可能会泄漏。

ES.60: Avoid new and delete outside resource management functions ES.60:避免新建和删除外部资源管理函数

Reason原因

Direct resource management in application code is error-prone and tedious.应用程序代码中的直接资源管理容易出错且乏味。

R.3: A raw pointer (a T*) is non-owning R.3:原始指针(T*)是非拥有的

Reason原因

There is nothing (in the C++ standard or in most code) to say otherwise and most raw pointers are non-owning.没有什么(在 C++ 标准或大多数代码中)另有说明,并且大多数原始指针都是非拥有的。 We want owning pointers identified so that we can reliably and efficiently delete the objects pointed to by owning pointers.我们希望识别拥有指针,以便我们可以可靠有效地删除拥有指针指向的对象。 (Owning pointers are pointers which take ownership of a pointer and are responsible for freeing it.) (拥有指针是拥有指针所有权并负责释放它的指针。)

Example例子

void f() { int* p1 = new int{7}; // bad: raw owning pointer auto p2 = make_unique<int>(7); // OK: the int is owned by a unique pointer //... }

So, the answer is use pointers only when you absolutely need to, otherwise stick to references and values.因此,答案是仅在绝对需要时才使用指针,否则坚持使用引用和值。

When to use pointers?什么时候使用指针?

  • When you are doing polymorphism (use smart pointers)当你在做多态时(使用智能指针)
  • When you are need a huge array (> 1MB) because stack size is limited.当您需要一个巨大的数组(> 1MB)时,因为堆栈大小有限。 ( 2 - 8 MB(usually) on linux , 1 MB on windows ). linux 上 2 - 8 MB(通常),windows1 MB )。 Prefer using std::vector in this case if you can.如果可以的话,最好在这种情况下使用std::vector
  • Pointers can sometimes be necessary when you are using "C" libraries or dealing with legacy C++ code.当您使用“C”库或处理遗留C++ 代码时,有时可能需要指针。

The critical difference between your two examples is memory allocation and lifetimes.您的两个示例之间的关键区别是 memory 分配和生命周期。

Anything allocated by using new is allocated on the heap and must be de-allocated by calling delete .使用new分配的任何内容都分配在堆上,必须通过调用delete取消分配。 In your first example, you have created a memory leak, as the Car is never de-allocated.在您的第一个示例中,您创建了一个 memory 泄漏,因为 Car 永远不会被取消分配。 In modern C++ you should largely not use new or delete but instead use smart pointers (something like auto c = std::make_unique<Car>(); )在现代 C++ 中,你应该主要不使用newdelete而是使用智能指针(类似于auto c = std::make_unique<Car>();

The reason why you would want do this, would be to generate something which outlives the scope of the function.你想要这样做的原因是为了生成比 function 的 scope 更长寿的东西。

In your second example the Car is created on the stack and is de-allocated when it goes out of scope (when the function returns).在您的第二个示例中, Car 是在堆栈上创建的,当它离开 scope 时(当 function 返回时)被取消分配。

I'm currently learning C++ and I can't wrap my head around why one would define an object of a class as a pointer (ie Car *c = new Car; as opposed to Car c; ) for no apparent reason? I'm currently learning C++ and I can't wrap my head around why one would define an object of a class as a pointer (ie Car *c = new Car; as opposed to Car c; ) for no apparent reason?

Take for example:举个例子:

#include <iostream>

class Car {
   public:
   void accelerate() { std::cout << "Accelerating!.\n"; }
};

int main() {
   Car *c = new Car;

   c->accelerate();

   return 0;
}

Why would one do it like that when it is much more intuitive to do it like this:当这样做更直观时,为什么要这样做:

#include <iostream>

class Car {
   public:
   void accelerate() { std::cout << "Accelerating!.\n"; }
};

int main() {
   Car c;

   c.accelerate();

   return 0;
}

If a pointer to the object is ever needed, one could always declare one, no?如果需要指向 object 的指针,总是可以声明一个,不是吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM