tìm câu trả lời thỏa đáng cho sự khác biệt giữa Malloc và New

Nguyễn Xuân Sơn
(NguyenXuanSon)

New Member
mình có câu hỏi sau mà chưa có câu trả lời thỏa đáng, mong các bạn bo it thoi gian giúp mình:


“Why is ”new” a C++ language-level construct while “malloc” is a library function?”


Mình có search google nhưng có lẽ keyword search không tốt nên chưa thấy gì cả.
Cảm ơn các bạn trước.
Xs
 
Hự hự, hỏi kiểu nì chẳng khác rì tại seo người ta lại dùng ký tự * để khai báo pointer trong C & C++. new mới được thêm vào ở C++ vì malloc rắc rối hơn nhìu, ví dụ như để cấp phát bộ nhớ cho 1 biến kiểu int với C++ chỉ cần
Mã:
int *a;
a = new int;
trong khi với C thì phải
Mã:
#include <malloc.h>
...
int *a;
a = (int*)malloc(sizeof(int));
Cái rì mà phần lớn các chương trình đều cần thì tốt nhất là nên để nó là language-level construct còn những cái chỉ có 1 số chương trình cần đến thì tốt nhất là nên để nó là library function.
 
À, có lẽ là tại cí nì, new có thể nhận 1 kiểu là đối số, trong khi nếu là 1 hàm thì ko thể nhận 1 kiểu là đối số được vì hàm sẽ hiểu tên kiểu (ở ví dụ trên là int) là tên 1 biến ---> sẽ gây ra lỗi vì tên biến trùng với tên kiểu ----> new chỉ có thể là language-level construct.
 
Hieu co thể nói rõ hơn, +reference chi tiết hơn? Em có thể reply bằng tiếng ANH.
XS
PS: vua vao trang web cua Hieu, may laptop cua Hieu sao toc do cham va it ram the, loai day cha con ai dung nua ca :)
 
Chỉnh sửa lần cuối:
Anh không phải dân C/C++, cũng 0 hiểu câu hỏi của Sơn, nhưng cảm thấy thế này:

1.) malloc đã được dùng quá nhiều như 1 library function, bây giờ có muốn đổi kiểu sang dùng như new cũng 0 được nữa. Thử tưởng tượng tự dưng thay
a= (int *) malloc(sizeof(int));
sang thành
a = malloc(int); hay là
a = malloc int;
thì chả còn chương trình C nào dùng được nữa, cứ là vứt sọt rác hết, viết code lại hết, nhá :)
2.) gọi constructor bằng keyword new nghe quen tai hơn
3.) new giá trị ở chỗ nó gọi cả 1 cái constructor chứ 0 phải chỉ để thay thế malloc
...

con laptop của anh có mỗi 1 GHz :-(
 
dạ, cái này là em bị hỏi, cho nên cũng chỉ biết hỏi lại mọi người thôi ạ, mong mọi người thông cảm...(mà em mà hiểu nó hỏi gì thì có lẽ cũng đã tự trả lời rồi:)

Em hiểu mang máng là bọn này muốn mình làm rõ ý sau:
1/ malloc là tàn dư của C (nhung tại sao lại là library function?). No không redefine được như new)
2/ new chỉ dùng trong C++, redefine, va (? co gọi đến malloc ?), em vẫn chưa hiểu chúng minh new là một operator được viết ở C++ level như thế nào cả?

Bọn chó chết (bọn Deutsche nó hỏi em đấy ạ)

Máy em hơn một năm vẫn đỉnh nhất hạng (Centrino 1.7, 1Gb ram, 1900*1200 15 untra wide screen, 60gb hdd :)
XS
 
Chỉnh sửa lần cuối:
Anh nghĩ nó nói "operator được viết ở C++ level" ám chỉ new có thể overriden cho từng class. Malloc không làm được điều này (libary cho gì thì được nấy :D)
 
Vũ Thanh Điềm đã viết:
Anh nghĩ nó nói "operator được viết ở C++ level" ám chỉ new có thể overriden cho từng class. Malloc không làm được điều này (libary cho gì thì được nấy :D)

Trả lời như Điềm cũng đúng đấy.

malloc được define trong malloc.h

void * malloc(size_t size);
void * realloc(void *ptr, size_t size);
void * calloc(size_t n, size_t size);
void * memalign(size_t align, size_t size);
void free(void * ptr);

C thì 0 hỗ trợ override, cho nên mới phải có malloc, realloc, calloc phức tạp thế, có được nó như là 1 library function đã là may lắm rồi.

còn new, là 1 dạng operator, thì trong C++ có thể override, đến operator+ còn override được nữa là new. Sơn xem trong

http://gethelp.devx.com/techtips/cpp_pro/10min/10min1100.asp

bọn nó nói về override new operator, hoặc globally, hoặc per-class basis.
 
Ngô Nguyễn Duy đã viết:
Vũ Thanh Điềm đã viết:
Anh nghĩ nó nói "operator được viết ở C++ level" ám chỉ new có thể overriden cho từng class. Malloc không làm được điều này (libary cho gì thì được nấy :D)

Trả lời như Điềm cũng đúng đấy.

malloc được define trong malloc.h

void * malloc(size_t size);
void * realloc(void *ptr, size_t size);
void * calloc(size_t n, size_t size);
void * memalign(size_t align, size_t size);
void free(void * ptr);

C thì 0 hỗ trợ override, cho nên mới phải có malloc, realloc, calloc phức tạp thế, có được nó như là 1 library function đã là may lắm rồi.

còn new, là 1 dạng operator, thì trong C++ có thể override, đến operator+ còn override được nữa là new. Sơn xem trong

http://gethelp.devx.com/techtips/cpp_pro/10min/10min1100.asp

bọn nó nói về override new operator, hoặc globally, hoặc per-class basis.
Em ko đồng ý lém với cách giải thích của anh Duy vì theo em hiểu thì ý anh Duy đang nói đến overload, trong C++ quá tải hàm dễ hơn quá tải toán tử rất rất nhìu ---> đó ko thể là lý do.

Giải thích lại bài viết trên của em: new nhận 1 kiểu là đối số (ví dụ như: i = new int) ----> new ko thể là hàm vì nếu là hàm thì nó sẽ như sau: i = new(int) ---> trong trường hợp nì, C++ sẽ hiểu int là 1 tên biến ---> sẽ thông báo lỗi vì nó nghĩ là người dùng sử dụng tên biến trùng với tên kiểu ---> sai rành rành.

Khè, cái laptop của em, cái đấy là còn nhanh đấy, bi giờ cái đấy hỏng rùi, em đang phải dùng cái 700MHz & 128MB RAM nì. Đang ko biết nên sửa cái máy cũ hay mua máy mới đây. Với lại, theo em thì máy 2GHz & 256MB RAM chỉ là ít với desktop còn với laptop thì như thế đã là tốt lém rùi (mấy cái máy mới cứng đang bán ở ngoài hàng với giá 800 bảng ở Anh cũng chỉ tầm 2.4GHz & 512MB RAM) trong khi cái máy của em mua từ năm ngoái lận.
 
Đặng Trần Hiếu đã viết:
Em ko đồng ý lém với cách giải thích của anh Duy vì theo em hiểu thì ý anh Duy đang nói đến overload, trong C++ quá tải hàm dễ hơn quá tải toán tử rất rất nhìu ---> đó ko thể là lý do.
Về nguyên tắc thì chả có cái nào khó hơn cái nào. Nhưng đó không phải là ý chính. Nhìn theo khía cạnh object oriented thì new là một "member function" của class, và đã được tự động "overload" cho mỗi class (new Fred khác với new Frod). Còn malloc thì thậm chí không thèm biết hàm là ai (return void*, không gọi constructor, và nếu dùng malloc(sizeof(int)) hay malloc(4) thì cũng chả khác gì nhau trên một số máy).

Đặng Trần Hiếu đã viết:
Giải thích lại bài viết trên của em: new nhận 1 kiểu là đối số (ví dụ như: i = new int) ----> new ko thể là hàm vì nếu là hàm thì nó sẽ như sau: i = new(int) ---> trong trường hợp nì, C++ sẽ hiểu int là 1 tên biến ---> sẽ thông báo lỗi vì nó nghĩ là người dùng sử dụng tên biến trùng với tên kiểu ---> sai rành rành.

Đây chỉ là một feature trong syntax của new. new(int) hoàn toàn hợp lệ và biên dịch như thường. int trong trường hợp này có thể coi là variable đặc biệt, <classtype> variable. Hàm có syntax tương tự như new trong C (mà cũng thường dùng với malloc) là sizeof.
 
Vũ Thanh Điềm đã viết:
Về nguyên tắc thì chả có cái nào khó hơn cái nào. Nhưng đó không phải là ý chính. Nhìn theo khía cạnh object oriented thì new là một "member function" của class, và đã được tự động "overload" cho mỗi class (new Fred khác với new Frod). Còn malloc thì thậm chí không thèm biết hàm là ai (return void*, không gọi constructor, và nếu dùng malloc(sizeof(int)) hay malloc(4) thì cũng chả khác gì nhau trên một số máy).
Thế "tự động overload cho mỗi class", cái này thì chưa chắc chắn được. Nếu em hiểu ko lầm thì ý anh ở đây là dựa vào đối số mà new sẽ cung cấp bộ nhớ tương đương, ví dụ như new int & new float. Tuy nhiên nếu là hàm thì nó vẫn có thể dựa vào đối số rùi dùng sizeof để cấp phát bộ nhớ tương đương cơ muh ---> theo cách lý giải của anh, chẳng có lý do gì để nó là language-level construct cả.
Đây chỉ là một feature trong syntax của new. new(int) hoàn toàn hợp lệ và biên dịch như thường. int trong trường hợp này có thể coi là variable đặc biệt, <classtype> variable. Hàm có syntax tương tự như new trong C (mà cũng thường dùng với malloc) là sizeof.
sizeof ko phải là "hàm", nó là 1 operator.
 
Đặng Trần Hiếu đã viết:
Thế "tự động overload cho mỗi class", cái này thì chưa chắc chắn được. Nếu em hiểu ko lầm thì ý anh ở đây là dựa vào đối số mà new sẽ cung cấp bộ nhớ tương đương, ví dụ như new int & new float. Tuy nhiên nếu là hàm thì nó vẫn có thể dựa vào đối số rùi dùng sizeof để cấp phát bộ nhớ tương đương cơ muh ---> theo cách lý giải của anh, chẳng có lý do gì để nó là language-level construct cả.

Có thể anh không hoàn toàn chính xác về "tự động overload", nhưng chắc chắn là có sự "can thiệp" của compiler cho new (thêm phần code để gọi constructor và cast to the right type). Còn malloc là fixed code, nằm trong một cái dll nào đớ, và compiler chỉ việc link đến thôi.

sizeof ko phải là "hàm", nó là 1 operator.

Anh không để ý lắm về từ ngữ ;), nhưng nói cho cùng thì operator cũng chỉ là một dạng function.
 
Vũ Thanh Điềm đã viết:
Đặng Trần Hiếu đã viết:
Thế "tự động overload cho mỗi class", cái này thì chưa chắc chắn được. Nếu em hiểu ko lầm thì ý anh ở đây là dựa vào đối số mà new sẽ cung cấp bộ nhớ tương đương, ví dụ như new int & new float. Tuy nhiên nếu là hàm thì nó vẫn có thể dựa vào đối số rùi dùng sizeof để cấp phát bộ nhớ tương đương cơ muh ---> theo cách lý giải của anh, chẳng có lý do gì để nó là language-level construct cả.

Có thể anh không hoàn toàn chính xác về "tự động overload", nhưng chắc chắn là có sự "can thiệp" của compiler cho new (thêm phần code để gọi constructor và cast to the right type). Còn malloc là fixed code, nằm trong một cái dll nào đớ, và compiler chỉ việc link đến thôi.

sizeof ko phải là "hàm", nó là 1 operator.

Anh không để ý lắm về từ ngữ ;), nhưng nói cho cùng thì operator cũng chỉ là một dạng function.
Tất nhiên là language-level construct thì phải khác với library function rùi. Nhưng mà ý em là nếu ko phải vì new nhận 1 kiểu làm đối số thì new hoàn toàn có thể là library function ---> có lẽ cách giải thích của anh ko được thuyết phục cho lém.

Còn operator thì khác hẳn với library function đấy. Nó giống với language-level construct hơn vì nó là thành phần cơ bản của ngôn ngữ, ko giống như library function, library function có thể có với compiler này nhưng lại ko có với compiler khác tùy vào nhà sản xuất compiler & library function phải include header có prototype của function đó mới dùng được, language-level construct thì ko vì nó là thành phần cơ bản của ngôn ngữ.

Chính vì thế nên em nghĩ là lý do new phải là language-level construct là vì function ko thể nhận 1 kiểu làm đối số, function chỉ có thể nhận 1 giá trị làm đối số. Dù seo đây cũng chỉ là phỏng đoán qua suy luận thui, chẳng có tài liệu chính thức nào cả nhưng dù seo thì nghe cũng có vẻ có lý. :-? :-?
 
Chỉnh sửa lần cuối:
Đặng Trần Hiếu đã viết:
Vũ Thanh Điềm đã viết:
Đặng Trần Hiếu đã viết:
Thế "tự động overload cho mỗi class", cái này thì chưa chắc chắn được. Nếu em hiểu ko lầm thì ý anh ở đây là dựa vào đối số mà new sẽ cung cấp bộ nhớ tương đương, ví dụ như new int & new float. Tuy nhiên nếu là hàm thì nó vẫn có thể dựa vào đối số rùi dùng sizeof để cấp phát bộ nhớ tương đương cơ muh ---> theo cách lý giải của anh, chẳng có lý do gì để nó là language-level construct cả.

Có thể anh không hoàn toàn chính xác về "tự động overload", nhưng chắc chắn là có sự "can thiệp" của compiler cho new (thêm phần code để gọi constructor và cast to the right type). Còn malloc là fixed code, nằm trong một cái dll nào đớ, và compiler chỉ việc link đến thôi.

sizeof ko phải là "hàm", nó là 1 operator.

Anh không để ý lắm về từ ngữ ;), nhưng nói cho cùng thì operator cũng chỉ là một dạng function.
Tất nhiên là language-level construct thì phải khác với library function rùi. Nhưng mà ý em là nếu ko phải vì new nhận 1 kiểu làm đối số thì new hoàn toàn có thể là library function ---> có lẽ cách giải thích của anh ko được thuyết phục cho lém.

Còn operator thì khác hẳn với library function đấy. Nó giống với language-level construct hơn vì nó là thành phần cơ bản của ngôn ngữ, ko giống như library function, library function có thể có với compiler này nhưng lại ko có với compiler khác tùy vào nhà sản xuất compiler & library function phải include header có prototype của function đó mới dùng được, language-level construct thì ko vì nó là thành phần cơ bản của ngôn ngữ.

Chính vì thế nên em nghĩ là lý do new phải là language-level construct là vì function ko thể nhận 1 kiểu làm đối số, function chỉ có thể nhận 1 giá trị làm đối số. Dù seo đây cũng chỉ là phỏng đoán qua suy luận thui, chẳng có tài liệu chính thức nào cả nhưng dù seo thì nghe cũng có vẻ có lý. :-? :-?


Nhận kiểu làm đối số (heh, cụm từ này nghe hoành tráng phết nhấy, ;) ) theo anh chỉ là một dạng ưu đãi đặc biệt cho new cũng như sizeof (mặc dù cho new, anh thấy nó giống như "pointer" to constructor hơn, vì em có thể dùng new int(10) etc). Nếu nhìn kỹ vào signature của new, em sẽ khá ngạc nhiên là nó hoàn toàn giống malloc:
void* operator new (size_t)

Thế nhưng khi new đựơc gọi, thì không chỉ có function này đựơc gọi mà cả constructor cũng được gọi. Phần code đó là do compiler nhét vào, dựa trên "sự hiểu biết về luât" của new trong C++.

Tuy nhiên bảo vì new là operator nên nó là language-level construct cũng có lý, vì đã là operator thì tất nhiên phải được "language" approve ;). Tuy nhiên hầu hết các operator khác em có thể overload thoải mái, không chịu ràng buộc như new, và nhiều operator (như +, - etc) không tồn tại nếu em không define cho class của em).

Tóm lại, ý của anh là code cho new là code động, được compiler tạo ra dựa trên "bộ luật" về new, còn malloc là code tĩnh, trốn trong một thư viện nào đó.
 
Vũ Thanh Điềm đã viết:
Đặng Trần Hiếu đã viết:
Vũ Thanh Điềm đã viết:
Đặng Trần Hiếu đã viết:
Thế "tự động overload cho mỗi class", cái này thì chưa chắc chắn được. Nếu em hiểu ko lầm thì ý anh ở đây là dựa vào đối số mà new sẽ cung cấp bộ nhớ tương đương, ví dụ như new int & new float. Tuy nhiên nếu là hàm thì nó vẫn có thể dựa vào đối số rùi dùng sizeof để cấp phát bộ nhớ tương đương cơ muh ---> theo cách lý giải của anh, chẳng có lý do gì để nó là language-level construct cả.

Có thể anh không hoàn toàn chính xác về "tự động overload", nhưng chắc chắn là có sự "can thiệp" của compiler cho new (thêm phần code để gọi constructor và cast to the right type). Còn malloc là fixed code, nằm trong một cái dll nào đớ, và compiler chỉ việc link đến thôi.

sizeof ko phải là "hàm", nó là 1 operator.

Anh không để ý lắm về từ ngữ ;), nhưng nói cho cùng thì operator cũng chỉ là một dạng function.
Tất nhiên là language-level construct thì phải khác với library function rùi. Nhưng mà ý em là nếu ko phải vì new nhận 1 kiểu làm đối số thì new hoàn toàn có thể là library function ---> có lẽ cách giải thích của anh ko được thuyết phục cho lém.

Còn operator thì khác hẳn với library function đấy. Nó giống với language-level construct hơn vì nó là thành phần cơ bản của ngôn ngữ, ko giống như library function, library function có thể có với compiler này nhưng lại ko có với compiler khác tùy vào nhà sản xuất compiler & library function phải include header có prototype của function đó mới dùng được, language-level construct thì ko vì nó là thành phần cơ bản của ngôn ngữ.

Chính vì thế nên em nghĩ là lý do new phải là language-level construct là vì function ko thể nhận 1 kiểu làm đối số, function chỉ có thể nhận 1 giá trị làm đối số. Dù seo đây cũng chỉ là phỏng đoán qua suy luận thui, chẳng có tài liệu chính thức nào cả nhưng dù seo thì nghe cũng có vẻ có lý. :-? :-?


Nhận kiểu làm đối số (heh, cụm từ này nghe hoành tráng phết nhấy, ;) ) theo anh chỉ là một dạng ưu đãi đặc biệt cho new cũng như sizeof (mặc dù cho new, anh thấy nó giống như "pointer" to constructor hơn, vì em có thể dùng new int(10) etc). Nếu nhìn kỹ vào signature của new, em sẽ khá ngạc nhiên là nó hoàn toàn giống malloc:
void* operator new (size_t)

Thế nhưng khi new đựơc gọi, thì không chỉ có function này đựơc gọi mà cả constructor cũng được gọi. Phần code đó là do compiler nhét vào, dựa trên "sự hiểu biết về luât" của new trong C++.

Tuy nhiên bảo vì new là operator nên nó là language-level construct cũng có lý, vì đã là operator thì tất nhiên phải được "language" approve ;). Tuy nhiên hầu hết các operator khác em có thể overload thoải mái, không chịu ràng buộc như new, và nhiều operator (như +, - etc) không tồn tại nếu em không define cho class của em).

Tóm lại, ý của anh là code cho new là code động, được compiler tạo ra dựa trên "bộ luật" về new, còn malloc là code tĩnh, trốn trong một thư viện nào đó.
Khè, trong ví dụ trên thì int là 1 kiểu & nó là đối số của new ---> ko gọi là "nhận kiểu làm đối số" thì phải gọi thế nèo?? Anh lạ nhỉ??

Còn theo anh, đó chỉ là 1 dạng ưu đãi đặc biệt cho new & sizeof vậy thì tại seo new ko thể là library function?? Nếu như đã cố tình cho new ưu đãi đặc biệt đó thì dù nó có là library function vẫn có thể cho nó ưu đãi đặc biệt được chứ?? Vả lại, có phải library function ko thể overload đâu??

Cái syntax của new mà anh đưa ra mới nhìn em đã thấy sai rùi vì nếu nó là
void* operator new (size_t)
thì dùng new int(10) sẽ sai vì 10 là size_t còn int thì nó là cái rì trong cú pháp trên?? Hơn nữa, cú pháp của anh phản lại điều anh nói là "new chỉ là pointer to construct", dựa vào đâu mà anh nói nó là pointer to constructor?? Nếu dựa vào cú pháp trên thì em chỉ thấy là kết quả trả lại của nó là void pointer thui chứ bản thân new thì em chưa thấy được nó là pointer đến constructor nèo cả?? Vậy theo anh nó là pointer đến constructor nèo?? Hơn nữa, cái từ khóa operator trên cú pháp trên đã chỉ rõ nó là 1 language-level construct rùi vì operator là language-level construct.

Anh bảo nhiều operator (+, -, etc.) ko tồn tại nếu em ko define cho class của em ---> sai. Lý do là vì ngay cả trong C anh vẫn có thể dùng +, - thoải mái mà trong C thì chưa có đến khái niệm class. Nếu anh nói là +, - ko tồn tại nếu em o define cho class của em thì anh thử dẫn chứng 1 class nèo đó anh viết mà +, - ko thể sử dụng vì anh chưa define xem nèo??

Nói gì thì nói, language-level construct & library function khác nhau hoàn toàn. Đố anh tìm được library function nèo mà có thể nhận kiểu làm đối số đấy. Còn language-level construct thì em đã chỉ ra được 2 là new & sizeof rùi.
 
Chỉnh sửa lần cuối:
Đặng Trần Hiếu đã viết:
Khè, trong ví dụ trên thì int là 1 kiểu & nó là đối số của new ---> ko gọi là "nhận kiểu làm đối số" thì phải gọi thế nèo?? Anh lạ nhỉ??

Hì, anh có định giễu đâu. Anh không học máy tính ở vn nên nghe mấy từ đối số thấy vui vui thôi :)

Còn theo anh, đó chỉ là 1 dạng ưu đãi đặc biệt cho new & sizeof vậy thì tại seo new ko thể là library function?? Nếu như đã cố tình cho new ưu đãi đặc biệt đó thì dù nó có là library function vẫn có thể cho nó ưu đãi đặc biệt được chứ?? Vả lại, có phải library function ko thể overload đâu??

Như anh đã nói ở trước, trả lời "là operator" nên là language-level cũng đúng. Nhưng anh muốn nói rằng không phải vì new có "kiểu dáng" đặc biệt nên nó là op, mà có lẽ ngược lại, vì đã để nó là op nên C++ cho phép nó có kiểu dáng đặc biệt. Các op khác cũng đều mỗi thằng một vẻ, thế nhưng nếu em định overload, lại thấy nó chẳng khác gì nguời thường, ngoại trừ một cái tag operator dính trên mũ. Mặt khác, cũng có những function "hình thù" kỳ dị mà có lẽ em không để ý, cụ thể là constructor và destructor.

Cái syntax của new mà anh đưa ra mới nhìn em đã thấy sai rùi vì nếu nó là
void* operator new (size_t)
thì dùng new int(10) sẽ sai vì 10 là size_t còn int thì nó là cái rì trong cú pháp trên??
Thế anh mới bảo là em sẽ ngạc nhiên mà. C'est la vie. :D

Hơn nữa, cú pháp của anh phản lại điều anh nói là "new chỉ là pointer to construct", dựa vào đâu mà anh nói nó là pointer to constructor?? Nếu dựa vào cú pháp trên thì em chỉ thấy là kết quả trả lại của nó là void pointer thui chứ bản thân new thì em chưa thấy được nó là pointer đến constructor nèo cả?? Vậy theo anh nó là pointer đến constructor nèo?? Hơn nữa, cái từ khóa operator trên cú pháp trên đã chỉ rõ nó là 1 language-level construct rùi vì operator là language-level construct.

Em hiểu sai ý anh rồi. Anh không nói new là pointer ..., mà nói cái đứng sau nó (int(10) chẳng hạn). Ngoài ra anh để pointer trong ngoặc kép, ý nói có thể hình dung theo cách đó, dĩ nhiên nó không thực sự là pointer. Lý do anh nói vậy là do công đoạn của new gồm 2 phần:

1. Tạo bộ nhớ cho object mới (hoàn toàn giống như malloc đã làm, có thể overload bằng cách viết lại cái op ở trên)
2. Gọi constructor. Nếu em dùng a= new Fred, thì nó sẽ gọi default constructor Fred(), còn nếu em dùng a= new Fred(10) thì nó sẽ gọi constructor Fred(int).

Anh bảo nhiều operator (+, -, etc.) ko tồn tại nếu em ko define cho class của em ---> sai. Lý do là vì ngay cả trong C anh vẫn có thể dùng +, - thoải mái mà trong C thì chưa có đến khái niệm class. Nếu anh nói là +, - ko tồn tại nếu em o define cho class của em thì anh thử dẫn chứng 1 class nèo đó anh viết mà +, - ko thể sử dụng vì anh chưa define xem nèo??

Em lại hiểu sai ý anh rồi. Anh nói các op này cho "class của em", chứ không nói cho các primary type như int, char etc. Em muốn thử thì cứ viết một cái class mới rồi làm mấy cái op đấy xem.

Nói gì thì nói, language-level construct & library function khác nhau hoàn toàn. Đố anh tìm được library function nèo mà có thể nhận kiểu làm đối số đấy. Còn language-level construct thì em đã chỉ ra được 2 là new & sizeof rùi.

Anh có phủ nhận chí có op mới có kiểu đặc biệt này đâu. Kể ra phân tích op và syntax cái nào có trước thì cũng như gà và trứng. Anh chỉ muốn nói việc đưa new vào language-level có cái khác sâu xa hơn việc bản thân nó là op. Anh mà là Stroustrup thì anh đã biến new thành static member function rồi, anh em mình đỡ phải cãi nhau :D.
 
Vũ Thanh Điềm đã viết:
Như anh đã nói ở trước, trả lời "là operator" nên là language-level cũng đúng. Nhưng anh muốn nói rằng không phải vì new có "kiểu dáng" đặc biệt nên nó là op, mà có lẽ ngược lại, vì đã để nó là op nên C++ cho phép nó có kiểu dáng đặc biệt. Các op khác cũng đều mỗi thằng một vẻ, thế nhưng nếu em định overload, lại thấy nó chẳng khác gì nguời thường, ngoại trừ một cái tag operator dính trên mũ. Mặt khác, cũng có những function "hình thù" kỳ dị mà có lẽ em không để ý, cụ thể là constructor và destructor.
Lý do em nghĩ vì new có "kiểu dáng" đặc biệt nên nó là operator chứ ko phải ngược lại là vì nếu vì nó là operator nên nó có kiểu dáng đặc biệt thì tại seo lập trình viên C++ ko viết nó là library function ngay từ đầu mà cứ bắt nó phải là operator?? Hơn nữa, C++ chỉ là chuẩn, ngôn ngữ lập trình chính thức được implement bởi nhiều compiler khác nhau, cách viết chương trình cũng khác nhau ít nhiều tùy thuộc vào compiler (GCC cho Linux & Visual C++ của Windows), thế nhưng ko có 1 compiler nèo viết lại new?? Hơn nữa, việc operator có kiểu dáng thế nèo là do lập trình viên compiler quyết định, nếu muốn nó có dạng giống hệt như 1 hàm (sizeof là 1 ví dụ) là hoàn toàn có thể --> ko thể nói vì nó là operator nên nó có "kiểu dáng" đặc biệt được.
 
Đặng Trần Hiếu đã viết:
Vũ Thanh Điềm đã viết:
Như anh đã nói ở trước, trả lời "là operator" nên là language-level cũng đúng. Nhưng anh muốn nói rằng không phải vì new có "kiểu dáng" đặc biệt nên nó là op, mà có lẽ ngược lại, vì đã để nó là op nên C++ cho phép nó có kiểu dáng đặc biệt. Các op khác cũng đều mỗi thằng một vẻ, thế nhưng nếu em định overload, lại thấy nó chẳng khác gì nguời thường, ngoại trừ một cái tag operator dính trên mũ. Mặt khác, cũng có những function "hình thù" kỳ dị mà có lẽ em không để ý, cụ thể là constructor và destructor.
Lý do em nghĩ vì new có "kiểu dáng" đặc biệt nên nó là operator chứ ko phải ngược lại là vì nếu vì nó là operator nên nó có kiểu dáng đặc biệt thì tại seo lập trình viên C++ ko viết nó là library function ngay từ đầu mà cứ bắt nó phải là operator?? Hơn nữa, C++ chỉ là chuẩn, ngôn ngữ lập trình chính thức được implement bởi nhiều compiler khác nhau, cách viết chương trình cũng khác nhau ít nhiều tùy thuộc vào compiler (GCC cho Linux & Visual C++ của Windows), thế nhưng ko có 1 compiler nèo viết lại new?? Hơn nữa, việc operator có kiểu dáng thế nèo là do lập trình viên compiler quyết định, nếu muốn nó có dạng giống hệt như 1 hàm (sizeof là 1 ví dụ) là hoàn toàn có thể --> ko thể nói vì nó là operator nên nó có "kiểu dáng" đặc biệt được.

Không phải đâu là không phải đâu. Phần quan trọng của xây dựng một ngôn ngữ lập trình là tạo bộ "grammar" cho nó (ai học compiler hay formal language có thể giải thích cái này rõ hơn anh). Các công ty sản xuất compiler dựa vào đó để xây dựng các compiler của mình, nhưng không ai được tự ý thay đổi grammar cả. Nếu không, thì bây giờ em sẽ có một đống hỗn loạn, tất cả các code em viết cho gcc quẳng sang cho VS sẽ kêu la ầm ĩ hết cả.

Còn tại sao Stroustrup (tác giả của C++) chọn syntax đó cho new thì anh không biết; có thể bắt nguồn từ sizeof, có thể do sau nhiều lần thử nghiệm (Stroustrup bắt tay xây dựng C++ từ đầu 80, nhưng đên 85 mới release và 88 mới trở thành ISO, so sánh với các phiên bản C++ đầu tiên, cái em sử dụng bây giờ cũng có nhiều thay đổi về cú pháp). Hiển nhiên là cú pháp của new quá tiện lợi và được rộng rãi chấp nhận nên việc nó tồn tại và trở thành ISO không có gì đáng ngạc nhiên. Nhưng có thể khẳng định rằng, Stroustrup hoàn toàn có thể chọn syntax khác cho new mà không ảnh hưởng gì tới toàn bộ cấu trúc của C++.

Cái mà anh và em đang tranh cãi có vẻ đang đi xa dần nội dung câu hỏi :). Những ai đã và đang xin việc vào các công ty IT chắc đều có trong tay một lô những câu hỏi kiểu này. Hôm nào làm một chủ đề các câu hỏi thế này cũng khá là bổ ích và lý thú :D
 
Em chưa xem kỹ các bài trả lời nhưng nghĩ là malloc được giữ như library function để việc port các traditional program giữa C và C++ dễ dàng hơn. Với cả C++ được phát triển dựa trên C thì việc tận dụng lại những điễm mạnh của C cũng dễ hiểu.

Thêm nữa malloc làm việc với memory nên depend vào platform thành ra implement malloc in a libary cũng là điều tự nhiên.

Mặt khác, new là quy ước trên abstract data nên được define ở language level.

Cheers,
ĐTrang
 
Vũ Thanh Điềm đã viết:
Đặng Trần Hiếu đã viết:
Vũ Thanh Điềm đã viết:
Như anh đã nói ở trước, trả lời "là operator" nên là language-level cũng đúng. Nhưng anh muốn nói rằng không phải vì new có "kiểu dáng" đặc biệt nên nó là op, mà có lẽ ngược lại, vì đã để nó là op nên C++ cho phép nó có kiểu dáng đặc biệt. Các op khác cũng đều mỗi thằng một vẻ, thế nhưng nếu em định overload, lại thấy nó chẳng khác gì nguời thường, ngoại trừ một cái tag operator dính trên mũ. Mặt khác, cũng có những function "hình thù" kỳ dị mà có lẽ em không để ý, cụ thể là constructor và destructor.
Lý do em nghĩ vì new có "kiểu dáng" đặc biệt nên nó là operator chứ ko phải ngược lại là vì nếu vì nó là operator nên nó có kiểu dáng đặc biệt thì tại seo lập trình viên C++ ko viết nó là library function ngay từ đầu mà cứ bắt nó phải là operator?? Hơn nữa, C++ chỉ là chuẩn, ngôn ngữ lập trình chính thức được implement bởi nhiều compiler khác nhau, cách viết chương trình cũng khác nhau ít nhiều tùy thuộc vào compiler (GCC cho Linux & Visual C++ của Windows), thế nhưng ko có 1 compiler nèo viết lại new?? Hơn nữa, việc operator có kiểu dáng thế nèo là do lập trình viên compiler quyết định, nếu muốn nó có dạng giống hệt như 1 hàm (sizeof là 1 ví dụ) là hoàn toàn có thể --> ko thể nói vì nó là operator nên nó có "kiểu dáng" đặc biệt được.

Không phải đâu là không phải đâu. Phần quan trọng của xây dựng một ngôn ngữ lập trình là tạo bộ "grammar" cho nó (ai học compiler hay formal language có thể giải thích cái này rõ hơn anh). Các công ty sản xuất compiler dựa vào đó để xây dựng các compiler của mình, nhưng không ai được tự ý thay đổi grammar cả. Nếu không, thì bây giờ em sẽ có một đống hỗn loạn, tất cả các code em viết cho gcc quẳng sang cho VS sẽ kêu la ầm ĩ hết cả.

Còn tại sao Stroustrup (tác giả của C++) chọn syntax đó cho new thì anh không biết; có thể bắt nguồn từ sizeof, có thể do sau nhiều lần thử nghiệm (Stroustrup bắt tay xây dựng C++ từ đầu 80, nhưng đên 85 mới release và 88 mới trở thành ISO, so sánh với các phiên bản C++ đầu tiên, cái em sử dụng bây giờ cũng có nhiều thay đổi về cú pháp). Hiển nhiên là cú pháp của new quá tiện lợi và được rộng rãi chấp nhận nên việc nó tồn tại và trở thành ISO không có gì đáng ngạc nhiên. Nhưng có thể khẳng định rằng, Stroustrup hoàn toàn có thể chọn syntax khác cho new mà không ảnh hưởng gì tới toàn bộ cấu trúc của C++.

Cái mà anh và em đang tranh cãi có vẻ đang đi xa dần nội dung câu hỏi :). Những ai đã và đang xin việc vào các công ty IT chắc đều có trong tay một lô những câu hỏi kiểu này. Hôm nào làm một chủ đề các câu hỏi thế này cũng khá là bổ ích và lý thú :D
Đó, chính vì cái chuẩn mà anh đang nói đến đó, ko thể chỉ vì ý kiến riêng của 1 người dù người đó có là tác giả của C đi nữa mà có thể thay đổi cái quy tắc đã được sử dụng ngay từ những ngày đầu của C là "Ko được đặt tên biến trùng với tên kiểu" được ---> ko thể có ngoại lệ, nếu ko sẽ phá chuẩn ---> bắt buộc new phải là language-level construct.
 
Back
Bên trên