Sự khác biệt giữa 'toán tử mới' và 'toán tử mới'?


126

Sự khác biệt giữa "toán tử mới" và "toán tử mới" là gì?


3
Xin chào, bạn có thể vui lòng làm rõ câu hỏi? Hình như có lỗi đánh máy ở đâu đó.
Dima Malenko

17
Câu hỏi được diễn đạt chính xác, xem câu trả lời dưới đây. Phương pháp phân bổ động bộ nhớ là sử dụng 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".
Thomas Matthews

2
Làm thế nào để làm điều đó. Tôi là người mới và không biết.
Sandeep

Câu trả lời:


127

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.


18
+1, như một cụm từ khác, tiêu chuẩn sử dụng biểu thức mới xung quanh và chỉ một lần nó sử dụng toán tử mới để chỉ địa điểm gọi. Tôi có xu hướng làm tương tự: toán tử mới cho cấp phátbiểu thức mới cho việc sử dụng.
David Rodríguez - dribeas

3
Một biểu thức mới là toàn bộ cụm từ bắt đầu bằng mới. Vì vậy, những gì bạn gọi chỉ là phần "mới" của nó? Nếu gọi sai toán tử mới đó, thì chúng ta không nên gọi "sizeof" toán tử sizeof hoặc & địa chỉ của toán tử (khi nó hoạt động như một toán tử).
Kaz

1
Theo dõi nhận xét của Kaz, có lẽ câu hỏi nên được nhắc lại là, sự khác biệt giữa toán tử mới và toán tử mới là gì? :)
CS

2
"Toán tử mới" so với "từ khóa mới"
user997112

2
@antred: Bạn sẽ phát hành nó với một cái gì đó như operator delete(x);.
Jerry Coffin

35

"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 +()


13
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 newdeletekhông. newdeletelà 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ệnxóa biểu hiện .
AnT

2
Uh, nếu bất cứ điều gì, sizeoflà cấu trúc cú pháp, và newdeleteđề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, newdeletelà cả hai nhà khai thác. Xem [cplusplus.com] [ cplusplus.com/doc/tutorial/groupes2/]
Austin Hyde

7
Sai. Thuật ngữ C ++ chính thức là thuật ngữ được xác định bởi đặc tả ngôn ngữ, không phải bởi một số trang web. Trong đặc tả ngôn ngữ không có nhiệt như "toán tử mới", nhưng có thuật ngữ như " operator newhàm". Một lần nữa, sizeofđược explicilty gọi là "điều hành", trong khi newdeleteđang không bao giờ được gọi là nhà khai thác.
AnT

6
AndreyT: Không chính xác. Chuẩn C ++ gọi 'toán tử' mới là toán tử, xem 13,5 / 1.

3
@AndreyT: Tôi nghĩ như bạn làm, toán tử mớicấp phátbiểu thức mới sử dụng. Tôi đã xem xét và kiểm tra rằng trong §5.3.4 / 3, tiêu chuẩn hiện tại sử dụng thuật ngữ toán tử mới . Sau đó trong §5.3.4 / 8, nó đặt tên cho các hàm cấp phát là toán tử mớitoán tử mới []
David Rodríguez - dribeas

22

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.


7
Thuật ngữ này rõ ràng được phát minh bởi tác giả của cuốn sách (hoặc, có thể, mượn từ một số nguồn lỗi thời). Trong danh pháp C ++ chính thức không có thuật ngữ như "toán tử mới".
AnT

2
@AndreyT: Tôi đã thực hiện tìm kiếm C ++ 11 cho "toán tử mới" và thấy nó được tham chiếu ở bốn nơi. Cụ thể, hai tài liệu tham khảo về "nhà điều hành mới vị trí"
Vịt Mooing

11

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ừ operatornewtrong 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ả.


14
Bạn dường như bị lạc trong một số thủ dâm tinh thần nhi đồng. Tiêu chuẩn là mơ hồ trong các điểm, và đây là một trong số đó. Việc "thảo luận về toán tử mới" cũng giống như "thảo luận về toán tử cộng" hoặc "thảo luận về toán tử +".

7

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ổ.


6

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.

2

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:

Chức năng mới của nhà điều hành

Toán tử mới


1
Làm rõ một chút: toán tử không vị trí mới phải luôn luôn gặp phải sự cố phân bổ (theo tiêu chuẩn); và các biểu mẫu vị trí, chẳng hạn như ::new(std::nothrow), có thể thực hiện (ví dụ cụ thể đó trả về một con trỏ null).

1
  1. 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.

  2. 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 đó.

  3. 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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.