Sự khác biệt giữa "toán tử mới" và "toán tử mới" là gì?
newtoán tử. Toán tử này có thể bị quá tải. Để phân biệt giữa toán tử mặc định và phiên bản quá tải, mặc định được gọi là "toán tử mới" và phiên bản quá tải được gọi là "toán tử mới".
Sự khác biệt giữa "toán tử mới" và "toán tử mới" là gì?
newtoán tử. Toán tử này có thể bị quá tải. Để phân biệt giữa toán tử mặc định và phiên bản quá tải, mặc định được gọi là "toán tử mới" và phiên bản quá tải được gọi là "toán tử mới".
Câu trả lời:
Tôi thường cố gắng diễn đạt những điều khác nhau để phân biệt giữa hai điều này tốt hơn một chút, nhưng đó là một câu hỏi hay trong mọi trường hợp.
Toán tử mới là một hàm phân bổ bộ nhớ thô - ít nhất là về mặt khái niệm, nó không khác nhiều so với malloc(). Mặc dù điều này khá bất thường trừ khi bạn viết một cái gì đó giống như thùng chứa của riêng bạn, bạn có thể gọi trực tiếp cho nhà điều hành, như:
char *x = static_cast<char *>(operator new(100));
Cũng có thể quá tải toán tử mới trên toàn cầu hoặc cho một lớp cụ thể. IIRC, chữ ký là:
void *operator new(size_t);
Tất nhiên, nếu bạn quá tải một toán tử mới (toàn cầu hoặc cho một lớp), bạn cũng sẽ muốn / cần quá tải xóa toán tử phù hợp. Đối với những gì đáng giá, cũng có một toán tử mới [] được sử dụng để phân bổ bộ nhớ cho các mảng - nhưng bạn gần như chắc chắn tốt hơn là bỏ qua toàn bộ mớ hỗn độn đó.
Toán tử mới là những gì bạn thường sử dụng để tạo một đối tượng từ cửa hàng miễn phí:
my_class *x = new my_class(0);
Sự khác biệt giữa hai là toán tử mới chỉ phân bổ bộ nhớ thô, không có gì khác. Toán tử mới bắt đầu bằng cách sử dụng toán tử new để cấp phát bộ nhớ, nhưng sau đó nó gọi hàm tạo cho đúng loại đối tượng, do đó kết quả là một đối tượng sống thực được tạo trong bộ nhớ đó. Nếu đối tượng đó chứa bất kỳ đối tượng nào khác (được nhúng hoặc dưới dạng lớp cơ sở) thì các hàm tạo đó cũng được gọi.
operator delete(x);.
"nhà điều hành mới"
class Foo
{
public:
void* operator new( size_t );
}
"Nhà điều hành mới":
Foo* foo = new Foo();
Trong ví dụ này, new Foo()các cuộc gọiFoo::operator new()
Nói cách khác, "toán tử mới" gọi " operator new()" giống như các cuộc gọi toán tử +operator +()
newkhông phải là một toán tử trong C ++. sizeof, Ví dụ, là một nhà điều hành, nhưng newvà deletekhông. newvà deletelà các từ khóa và các cấu trúc cú pháp mà các từ khóa này hình thức được gọi là mới thể hiện và xóa biểu hiện .
sizeoflà cấu trúc cú pháp, và newvà deleteđều, các nhà khai thác quá tải-thể pháp lý hợp lệ. Từ tất cả mọi thứ tôi từng thấy, newvà deletelà cả hai nhà khai thác. Xem [cplusplus.com] [ cplusplus.com/doc/tutorial/groupes2/]
operator newhàm". Một lần nữa, sizeofđược explicilty gọi là "điều hành", trong khi newvà deleteđang không bao giờ được gọi là nhà khai thác.
Sau đây là trích dẫn từ cuốn sách C ++ hiệu quả hơn từ Scott Meyers:
Toán tử mới gọi một hàm để thực hiện cấp phát bộ nhớ cần thiết và bạn có thể viết lại hoặc quá tải hàm đó để thay đổi hành vi của nó. Tên của hàm mà toán tử mới gọi để cấp phát bộ nhớ là toán tử mới.
Không có sự khác biệt giữa "toán tử mới" và "toán tử mới". Cả hai đều đề cập đến cùng một điều: hàm quá tải / có thể thay thế operator newthường thực hiện cấp phát bộ nhớ thô cho các đối tượng được tạo bởi biểu thức mới .
Cũng lưu ý rằng không có thuật ngữ nào xuất hiện trong đặc tả ngôn ngữ (là nguồn xác định của thuật ngữ chính thức).
Khi bạn sử dụng newtrong chương trình của mình để tạo một đối tượng, nó được gọi là biểu thức mới . Biểu thức mới bao gồm từ khóa newvà các phần cú pháp bổ sung được xác định bởi ngữ pháp. Không có phần nào trong cú pháp của biểu thức này được gọi là "toán tử".
Hàm cấp phát bộ nhớ thô operator newđược gọi chính thức là " operator newhàm". Lưu ý rằng các từ operatorvà newtrong chuỗi này chỉ là hai từ khóa ngôn ngữ C ++ riêng biệt. Họ không tạo thành một thuật ngữ tiếng Anh "toán tử mới". Không ở đâu trong đặc tả ngôn ngữ, bạn sẽ tìm thấy bất kỳ tài liệu tham khảo nào về "toán tử mới" như một thuật ngữ tiếng Anh. Mỗi lần đây chỉ là sự kết hợp của hai từ khóa độc lập tạo ra cú pháp khai báo cho hàm cấp phát bộ nhớ.
Một lần nữa, trong sơ yếu lý lịch: chính thức trong C ++, không có thuật ngữ tiếng Anh nào như "toán tử mới" hay "toán tử mới". Trình tự trước đây được trình bày trong đặc tả ngôn ngữ dưới dạng kết hợp các từ khóa, không phải là một thuật ngữ tiếng Anh. Sau này không có mặt ở tất cả.
Khi bạn tạo một đối tượng mới, bộ nhớ được cấp phát bằng toán tử new thì hàm tạo được gọi để khởi tạo bộ nhớ. Các nhà điều hành mới hiện cả hai việc phân bổ và khởi động, trong khi đó các nhà điều hành mới chỉ thực hiện việc phân bổ.
Câu hỏi của OP không được đặt đúng. Tốt hơn là nên pha như 'Sự khác biệt giữa' toán tử mới 'và' biểu thức mới '?' Lưu ý 'toán tử mới' cũng thường đề cập đến 'hàm toán tử mới'.
Và có rất nhiều câu trả lời đúng xung quanh, bên dưới là của tôi:
1> 'biểu thức mới' gọi 'toán tử mới' để phân bổ bộ nhớ thô, sau đó gọi hàm tạo
apple * p = new apple(); //new expression
2> 'toán tử mới' chỉ phân bổ bộ nhớ thô, không khác biệt nhiều so với malloc
void* mem = operator new(sizeof(apple)); //just like calling malloc()
apple* p2 = new(mem) apple(1); //call construct here using placement new.
Toán tử mới : C ++ hỗ trợ phân bổ động các đối tượng bằng toán tử mới. Toán tử mới phân bổ bộ nhớ cho các đối tượng từ một nhóm gọi là cửa hàng miễn phí. Toán tử mới gọi toán tử hàm đặc biệt mới.
Toán tử new : Nếu yêu cầu dành cho byte lưu trữ bằng 0, toán tử new trả về một con trỏ tới một đối tượng riêng biệt (nghĩa là các cuộc gọi lặp lại cho toán tử mới trả về các con trỏ khác nhau). Nếu không đủ bộ nhớ cho yêu cầu cấp phát, toán tử mới trả về NULL hoặc ném ngoại lệ. Đối số đầu tiên cho toán tử mới phải là kiểu size_t (một kiểu được xác định trong STDDEF.H) và kiểu trả về luôn luôn là void *.
Đây là một liên kết MSDN để biết thêm chi tiết:
mới là một nhà điều hành cũng như một từ khóa.
xem [1] Trong 2.13 && Trong 2.12.
mới làm hai điều: T * t = new T (arg);
1) cấp phát bộ nhớ cho đối tượng: void * ptr = toán tử new (sizeof (T));
// toán tử mới là một hàm (giống như malloc trong c), không phải là toán tử. (xem [1] Trong 3.7.4). Nhưng Mục 7 [2] cho biết đây cũng là một nhà điều hành. Theo tôi, sự khác biệt giữa toán tử và hàm là nhỏ và bạn có thể thấy nó khi bạn nhớ lại rằng toán tử nạp chồng được thực hiện bởi các hàm.
// chúng ta có thể quá tải toán tử / hàm này (toán tử mới) làm những gì chúng ta muốn ở đây.
2) khởi tạo đối tượng trong bộ nhớ được phân bổ: gọi T :: T (arg) trên ptr
// chỉ trình biên dịch có thể làm điều này. Cả tôi và bạn đều không thể.
// trình biên dịch cũng sẽ gọi các hàm tạo của đối tượng thành viên và hàm tạo của lớp cơ sở nếu T có chúng. Và lời cầu khẩn này là đệ quy. Chỉ có trình biên dịch có thể làm điều đó.
Vì vậy, toán tử mới thực hiện một phần nhiệm vụ mới và chỉ trong phần này chúng ta mới có thể làm gì đó.
[1]: ISO / IEC, N3690. http://ww.open-std.org/jtc1/sc22/wg21/docs/ con / 2013 / n3690.pdf
[2]: Meyers, Scott. C ++ hiệu quả, thứ 3.