Vì bạn đã hỏi;) có một công cụ trong C để tránh trùng lặp rõ ràng mã, macro. Điều đó nói rằng tôi không thấy một cách nào để không lặp lại ít nhất là tên của loại. Nhưng trong C++ họ không thể một trong hai, do đó, C là ít nhất là tốt :)
Các dễ nhất tôi thấy là
#define DESIGNATE_NEW(T) \
memcpy(malloc(sizeof(T)), \
&(T const){ __VA_ARGS__ }, \
sizeof(T))
mà sẽ cung cấp cho
Type *t = DESIGNATE_NEW(Type,
.a = 2,
.b = 3,
.c = 5,
);
này có một số lợi thế.
- Nó khởi tạo tất cả các thành viên một cách chính xác, ngay cả trên kiến trúc với không đại diện chuẩn của
0
với nhiều loại phao hoặc con trỏ.
- Khác với phiên bản của Keith, nó là "kiểu mã hóa" có thể chấp nhận được vì nó chỉ là một biểu thức giống như khởi tạo và bất kỳ ai nên chụp ngay lập tức những gì mã snipset thứ hai được cho là phải làm.
NB: Quan sát const
trong macro, điều này cho phép một số trường hợp của hợp chất chữ được gấp lại, nếu trình biên dịch quyết định điều này là có liên quan. Ngoài ra còn có phương tiện để có một biến thể trong đó danh sách các nhà thiết kế là tùy chọn, xem P99 bên dưới.
Bất lợi là memcpy
và tôi sẽ hạnh phúc hơn với bài tập. Thứ hai không có kiểm tra cho sự thất bại của malloc
trước khi sử dụng kết quả, nhưng người ta có thể có thể đi qua với một số weirdness để có mã thoát độc đáo.
Trong P99 Tôi đi một cách hơi khác. Ở đó chúng ta luôn luôn có một chức năng khởi tạo cho một loại, một cái gì đó giống như
inline
Type* Type_init(Type* t, int a, int b, int c) {
if (t) {
*t = (Type const){ .a = a, .b = b, .c = c };
}
return t;
}
mà theo kỳ diệu vĩ mô có thể được thực hiện để cung cấp luận cứ mặc định cho a
, b
và c
nếu họ bị bỏ qua.Sau đó, bạn có thể chỉ cần sử dụng một cái gì đó như
Type *t = P99_NEW(Type, 1, 2, 3);
trong mã ứng dụng của bạn. Điều này là tốt hơn, vì nó tránh dereferrencing con trỏ khi cuộc gọi đến malloc
không thành công. Mặt khác, việc này giới thiệu lại một đơn đặt hàng cho người khởi tạo, vì vậy không hoàn hảo.
Nếu có thể, điều gì sẽ xảy ra nếu 'malloc' trả về' NULL'? – detly
Có vẻ như bạn thực sự muốn có C++. –
Câu hỏi thú vị, nhưng tôi không nghĩ có câu trả lời hay. Cá nhân tôi sẽ chỉ sử dụng 'calloc' theo sau bởi' t-> a = 2; t-> b = 3; '... (' calloc' là chỉ có trong trường hợp bạn muốn để lại ra bất kỳ thành viên, vì vậy nếu bạn biết bạn sẽ rõ ràng đặt tất cả, bạn có thể sử dụng 'malloc' chỉ là tốt) –