2010-05-05 43 views
6

Xin chào các bạn. Tôi đang làm việc để sửa mã cũ hơn cho công việc của mình. Nó hiện đang được viết bằng C++. Họ đã chuyển đổi phân bổ tĩnh thành động nhưng không chỉnh sửa memsets/memcmp/memcpy. Đây là lần thực tập lập trình đầu tiên của tôi nên không có câu hỏi mới.Sử dụng ghi nhớ về cấu trúc trong C++

Mã sau đây là trong C, nhưng tôi muốn có nó trong C + + (tôi đọc rằng malloc là không thực hành tốt trong C + +). Tôi có hai kịch bản: Đầu tiên, chúng tôi đã tạo f. Sau đó, bạn sử dụng & f để điền bằng không. Thứ hai là một con trỏ * pf. Tôi không chắc chắn làm thế nào để đặt pf cho tất cả 0 như ví dụ trước trong C + +.

Bạn có thể làm pf = new foo thay vì malloc và sau đó gọi memset(pf, 0, sizeof(foo))?

struct foo { ... } f; 
memset(&f, 0, sizeof(f)); 

//or 

struct foo { ... } *pf; 
pf = (struct foo*) malloc(sizeof(*pf)); 
memset(pf, 0, sizeof(*pf)); 
+1

Nó phụ thuộc vào những gì trong foo! –

Trả lời

8

Có, nhưng chỉ khi foo là POD. Nếu nó có chức năng ảo hoặc bất cứ điều gì khác từ xa C++ ish, không sử dụng memset trên nó vì nó sẽ stomp trên tất cả các bên trong của struct/class.

Những gì bạn có thể muốn làm thay vì ghi nhớ là cung cấp cho foo một hàm tạo để khởi tạo rõ ràng các thành viên của nó.

Nếu bạn muốn sử dụng mới, đừng quên xóa tương ứng. Thậm chí tốt hơn sẽ được sử dụng shared_ptr :)

+0

Cảm ơn Ben. Sau khi xem xét một số tệp khác mà họ có, tôi nhận thấy họ đang sử dụng cách xóa mới để khởi tạo nhiều hơn so với việc tạo một hàm tạo cho cấu trúc. Tôi sẽ đi với điều đó vì họ không có chức năng ảo.Cảm ơn đã giúp đỡ. – garry

+0

@garry: khi sử dụng 'new', hàm tạo vẫn được gọi. Bạn có thể khởi tạo các thuộc tính của nó ở đó. –

+3

Minor pedantry trong cả C và C++, ngay cả với các loại POD, đó là hành vi không xác định về mặt kỹ thuật để chỉ đi xung quanh bằng cách sử dụng 'memset' đến bộ nhớ zero, và sau đó đọc bộ nhớ đó như bất cứ thứ gì khác ngoài' char' types và secure-no-padding các loại '(u) intN_t'. Trong thực tế, việc thực hiện của bạn sẽ sắp xếp cho tất cả-0-byte để có nghĩa là một con trỏ null, một phao 0.0 (như trong IEEE754), và vân vân, nhưng về mặt lịch sử, không phải tất cả các triển khai luôn làm điều này. –

2

Có, điều đó sẽ hiệu quả. Tuy nhiên, tôi không nghĩ rằng malloc là thực tế tồi tệ nhất, và tôi sẽ không thay đổi nó chỉ để thay đổi nó. Tất nhiên, bạn nên chắc chắn rằng bạn luôn luôn phù hợp với các cơ chế phân bổ đúng (mới-> xóa, malloc-> miễn phí, vv).

Bạn cũng có thể thêm một hàm tạo vào cấu trúc và sử dụng để khởi tạo các trường.

3

Bạn có thể? Có, có thể. Có nên không? Số

Mặc dù nó có thể hoạt động, bạn đang mất trạng thái mà hàm tạo đã xây dựng cho bạn. Thêm vào điều này, điều gì sẽ xảy ra khi bạn quyết định triển khai một lớp con của cấu trúc này? Sau đó, bạn mất lợi thế của mã reuseable C++ OOP cung cấp.

Điều bạn nên làm thay vào đó là tạo một hàm tạo khởi tạo các thành viên cho bạn. Bằng cách này, khi bạn sublass cấu trúc này sau này xuống dòng, bạn chỉ cần sử dụng constructor này để hỗ trợ bạn trong việc xây dựng các lớp con. Đây là mã miễn phí, an toàn! sử dụng nó!

Chỉnh sửa: Thông báo trước cho điều này là nếu bạn có cơ sở mã lớn, không thay đổi nó cho đến khi bạn bắt đầu phân lớp các cấu trúc. Nó hoạt động như bây giờ.

2

Bạn có thể mới foo (như là cách chuẩn trong C++) và thực hiện một constructor mà initialises foo hơn là sử dụng memset.

Ví dụ:

struct Something 
{ 
    Something() 
     : m_nInt(5) 
    { 

    } 

    int m_nInt; 
}; 

Cũng đừng quên nếu bạn sử dụng mới gọi xóa khi bạn kết thúc với các đối tượng nếu không bạn sẽ kết thúc với rò rỉ bộ nhớ.