2011-08-24 42 views
8

Đến từ một thế giới C#, tôi đang cố gắng đảm bảo rằng tôi không giới thiệu rò rỉ bộ nhớ và lỗi trong dự án C++ mà tôi đã được gán. Tôi đang viết mã sử dụng cấu trúc để phân tích thông tin từ bộ đệm dữ liệu. Bởi vì số lượng cấu trúc dữ liệu xuất hiện trong bộ đệm có thể thay đổi theo thời gian chạy, một vector stl được sử dụng để lưu trữ dữ liệu đã xử lý. Tôi đã xem qua các khối mã sau đây trong phần mềm hiện có, và đang đấu tranh để hiểu tại sao nó hoạt động:Phạm vi quản lý và tuổi thọ đối tượng Trong phạm vi STL Vectors

MyVectorOfObjects.clear(); 
for (unsigned __int8 i = 0; i < NumberOfObjects; i++) 
{ 
    MyParserObject parserObject;    // Declaring without 'new'? 
    parserObject.Decode(buffer, offset, size); // A method on the struct. 
    MyVectorOfObjects.push_back(parserObject); // Does this keep parserObject in scope? 
} 

Câu hỏi của tôi là cụ thể:

  1. Theo this question, sẽ không parserObject đi trong phạm vi mỗi lần lặp lại vì từ khóa new không được sử dụng? Rõ ràng mã này đã hoạt động.

  2. Trong trường hợp này, việc đặt đối tượng trong một vector giữ phạm vi parserObject trong phạm vi?

  3. Theo this question, trình phân tích cú phápObject được sao chép. Trong trường hợp này, các tác động hiệu suất (ví dụ: tiêu thụ bộ nhớ, cấp phát bộ nhớ, vv) của điều này là gì? Ngoài ra, làm sao chép các phân tích cú phápObjects sau đó giả định phạm vi tương tự như vectơ?

Cảm ơn bạn đã được trợ giúp.

+3

Đây là phần cơ bản C++. Tôi khuyên bạn nên lấy [cuốn sách giới thiệu C++ tốt] (http://tinyurl.com/so-cxxbooks) và học từ nó.Điều đó nói rằng, bạn cần nhận ra một sự khác biệt lớn giữa C++ và C#: Trong C++, các biến chứa * values ​​* (trừ khi được khai báo rõ ràng là tham chiếu), trong khi trong C#, hầu hết các biến chứa * references * (tất nhiên, không đếm loại giá trị). –

+0

Với 'MyParserObject parserObject;', bộ nhớ của nó được chương trình tự động quản lý - nghĩ về nó như là một 'delete parserObject;' ngay sau vòng lặp 'for', mặc dù điều này không nhất thiết xảy ra trong thực tế. –

+0

@ R.Martinho Cảm ơn bạn đã tham khảo ... và ghi chú. – bporter

Trả lời

7
  1. Vâng, trường hợp của parserObject được khai báo trong for lặp đi ra khỏi phạm vi mỗi lần lặp loop.

  2. Không, đặt parserObject vào vector không giữ đối tượng đó trong phạm vi. Phương thức push_back() sẽ tạo một bản sao của đối tượng đó hiện thuộc sở hữu của vector. Bạn cần phải chắc chắn rằng các đối tượng của bạn có thể được sao chép đúng cách (có thể cần phải có bản sao-constructor và toán tử gán). Các bản sao có trong vectơ trong ví dụ này thuộc sở hữu của vectơ, và sẽ có thời gian sống đối tượng tương tự với chính bản thân số vector.

  3. Bản sao paserObject được sao chép và điều này có thể có tác động đến việc sử dụng bộ nhớ và hiệu suất. Nếu parserObject không phải là tầm thường để sao chép thì đây có thể là một hoạt động tốn kém. Điều này hoàn toàn phụ thuộc vào việc bạn triển khai parserObject.

+0

Hai câu trả lời hay và tôi ước tôi có thể chấp nhận cả hai; buộc phải chọn, tuy nhiên, người này đã trả lời một cách rõ ràng các câu hỏi. Cảm ơn tất cả sự giúp đỡ. – bporter

4
MyVectorOfObjects.push_back(parserObject); // Does this keep parserObject in scope? 

push_back tạo bản sao của đối tượng và lưu trữ.

Vì vậy, hãy đảm bảo rằng bạn đã xác định sao chép-hàm tạo (và sao chép bài tập) đúng cho lớp MyParserObject nếu nó có con trỏ thành viên. Hoặc mã mặc định khác được tạo bởi trình biên dịch sẽ là đủ, miễn là mỗi thành viên của MyParserObject theo cùng một mẫu (tức là họ đã định nghĩa bản sao-constructor (và copy-assignment) đúng nếu chúng có thành viên con trỏ, hoặc mã mặc định khác được tạo ra bởi trình biên dịch sẽ là đủ, với điều kiện .... vv.)

+0

Vì vậy, điều này có nghĩa là mỗi parserObject được sao chép sẽ vẫn nằm trong phạm vi miễn là MyVectorOfObjects nằm trong phạm vi? – bporter

+0

@bporter. Có .... – Nawaz

+1

Nếu bạn đang làm việc với C++ 0x, thì hãy đảm bảo xác định hàm khởi tạo và di chuyển. –

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