簡體   English   中英

為什么有些人將對象定義為指針?

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

我目前正在學習 C++,我無法理解為什么有人會無緣無故地將 class 的 object 定義為指針(即Car *c = new Car;而不是Car c; )?

舉個例子:

#include <iostream>

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

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

   c->accelerate();

   return 0;
}

當這樣做更直觀時,為什么要這樣做:

#include <iostream>

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

int main() {
   Car c;

   c.accelerate();

   return 0;
}

如果需要指向 object 的指針,總是可以聲明一個,不是嗎?

為什么要將 class 的 object 定義為指針

一個不應該。 通常要盡可能避免使用指針。 但是,當您進行多態性時,它們是必需的。 在這種情況下,使用智能指針shared_ptrunique_ptr而不是原始指針。

下面是一個使用指針的壞例子,因為現在你有一個額外的問題,即“釋放分配的內存”。

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

你是對的,第二個例子要好得多,應該是 go 的默認方式。

每當出現此類問題時,最好看看C++ Core Guidelines是怎么說的:

R.11:避免顯式調用 new 和 delete

原因

new 返回的指針應該屬於資源句柄(可以調用 delete)。 如果將 new 返回的指針分配給普通/裸指針,則 object 可能會泄漏。

ES.60:避免新建和刪除外部資源管理函數

原因

應用程序代碼中的直接資源管理容易出錯且乏味。

R.3:原始指針(T*)是非擁有的

原因

沒有什么(在 C++ 標准或大多數代碼中)另有說明,並且大多數原始指針都是非擁有的。 我們希望識別擁有指針,以便我們可以可靠有效地刪除擁有指針指向的對象。 (擁有指針是擁有指針所有權並負責釋放它的指針。)

例子

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 //... }

因此,答案是僅在絕對需要時才使用指針,否則堅持使用引用和值。

什么時候使用指針?

  • 當你在做多態時(使用智能指針)
  • 當您需要一個巨大的數組(> 1MB)時,因為堆棧大小有限。 linux 上 2 - 8 MB(通常),windows1 MB )。 如果可以的話,最好在這種情況下使用std::vector
  • 當您使用“C”庫或處理遺留C++ 代碼時,有時可能需要指針。

您的兩個示例之間的關鍵區別是 memory 分配和生命周期。

使用new分配的任何內容都分配在堆上,必須通過調用delete取消分配。 在您的第一個示例中,您創建了一個 memory 泄漏,因為 Car 永遠不會被取消分配。 在現代 C++ 中,你應該主要不使用newdelete而是使用智能指針(類似於auto c = std::make_unique<Car>();

你想要這樣做的原因是為了生成比 function 的 scope 更長壽的東西。

在您的第二個示例中, 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?

舉個例子:

#include <iostream>

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

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

   c->accelerate();

   return 0;
}

當這樣做更直觀時,為什么要這樣做:

#include <iostream>

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

int main() {
   Car c;

   c.accelerate();

   return 0;
}

如果需要指向 object 的指針,總是可以聲明一個,不是嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM