2012-01-14 23 views
6

Tôi đang cố gắng hiểu các tác động /các tác dụng phụ/lợi thế của một thay đổi mã gần đây mà người khác đã thực hiện. Sự thay đổi như sau:Thay đổi mã này có mục đích gì?

gốc

static List<type1> Data; 

Modified

static List<type1> & getData (void) 
{ 
    static List<type1> * iList = new List<type1>; 
    return * iList; 
} 
#define Data getData() 

mục đích gì có thể thay đổi phục vụ?

+0

có lẽ để tránh một số loại khởi tạo tĩnh vấn đề? – Anycorn

+2

'#define Dữ liệu ...' chỉ yêu cầu sự cố – tenfour

+0

@ Lol4t0: bạn có thể giải thích thêm một chút về nhận xét của mình không? Làm thế nào là nó không thread an toàn? – Lazer

Trả lời

4

Lợi ích của bản sửa đổi mà tôi có thể thấy là một vấn đề của 'thời gian khởi tạo'.

Mã cũ kích hoạt khởi tạo trước khi main() được gọi.

Mã mới không kích hoạt khởi tạo cho đến khi getData() được gọi lần đầu tiên; nếu hàm này không bao giờ được gọi, bạn không bao giờ trả tiền để khởi tạo biến mà bạn không sử dụng. Nhược điểm (nhỏ) là có một khởi tạo kiểm tra trong mã được tạo ra mỗi khi chức năng được sử dụng, và có một cuộc gọi chức năng mỗi khi bạn cần truy cập vào danh sách dữ liệu.

+0

Điều gì về giá trị lâu dài khi nó được khởi tạo? Điều đó có giống nhau không? – Lazer

+0

Sau khi khởi tạo, nó kéo dài 'mãi mãi' (cho đến khi chương trình kết thúc). Nó sẽ bị phá hủy sạch sẽ, tôi tin rằng, nếu chương trình thoát khỏi tầm kiểm soát. (Oh, nhưng nó được phân bổ động, có thể nó chỉ là 'rò rỉ' khi chương trình thoát ra? Như vậy 'rò rỉ' là vô hại trừ khi kiểu dữ liệu nằm trong danh sách mua lại tài nguyên cần được chính thức phát hành khi chương trình thoát.) –

+0

@Lazer: Có. tuổi thọ giống như trong trường hợp mã ban đầu. –

3

Nếu bạn có biến có thời lượng tĩnh, nó được tạo khi ứng dụng được khởi tạo. Khi ứng dụng chấm dứt đối tượng bị hủy. Không thể kiểm soát thứ tự các đối tượng khác nhau được tạo ra.

Thay đổi sẽ làm cho đối tượng được tạo khi nó được sử dụng lần đầu tiên và (vì nó được phân bổ động) sẽ không bao giờ bị hủy.

Điều này có thể là một điều tốt nếu các đối tượng khác cần đối tượng này khi chúng bị phá hủy.

Cập nhật

Mã gốc truy cập các đối tượng sử dụng biến Data. Mã mới không phải được sửa đổi theo bất kỳ cách nào. Khi mã sử dụng Data, trên thực tế, sẽ sử dụng macro Data, sẽ được mở rộng thành getData(). Hàm này sẽ trả về một tham chiếu đến đối tượng thực tế (được phân bổ động). Trong thực tế, mã mới sẽ hoạt động như một thay thế thả cho mã cũ, với sự khác biệt đáng chú ý duy nhất là những gì tôi đã mô tả trong câu trả lời gốc ở trên.

+0

Có đối tượng sẽ không bị phá hủy, nhưng nó sẽ được truy cập như thế nào? – Lazer

+0

Nó sẽ được truy cập bất cứ khi nào ai đó gọi 'getData', Lazer. –

1

Việc trì hoãn việc xây dựng cho đến khi sử dụng lần đầu tiên Data tránh "static initialization order fiasco".

Thực hiện một số dự đoán về List, ... cấu hình mặc định Data có thể là danh sách trống của type1 mục, vì vậy có thể không có nguy cơ gây ra thất bại trong câu hỏi. Nhưng có lẽ ai đó cảm thấy tốt hơn để được an toàn hơn xin lỗi.

Các vấn đề liên quan