2015-04-16 14 views

Trả lời

5

Tất cả các đối tượng không phải đống sẽ nằm trong phân đoạn tĩnh, bên trong trường hợp tĩnh A().

Liên quan đến ghi đè, điều này có thể xảy ra trong C/C++ cũ hơn nếu bạn sử dụng nhiều thành ngữ đơn lẻ trong mã đa luồng. Nhưng ví dụ: phiên bản gcc mới hơn sử dụng các yêu cầu tiêu chuẩn mới để khởi tạo an toàn thread tự động của các đối tượng tĩnh. Xem ví dụ Is local static variable initialization thread-safe in C++11?

+0

Câu trả lời duy nhất cho đến nay chỉ ra sự khác biệt về hành vi của biến tĩnh trong bài và trước C++ 11 – senfen

+2

Chính xác hơn, bởi không * heap * bạn thực sự có nghĩa là không * động *. Các đối tượng được cấp phát động cũng có thể nằm trong phân đoạn tĩnh nếu một trình phân bổ tùy chỉnh được sử dụng. "Heap" là một chi tiết triển khai mà chỉ xảy ra được sử dụng nhiều nhất. –

+0

Hãy coi chừng rằng tôi không nghĩ rằng Visual C++ thực hiện chủ đề an toàn tĩnh initialisation (ma thuật statics) trước khi VS2015. – sjdowling

0

Biến a là biến tĩnh và chỉ được khai báo một lần, có nghĩa là câu lệnh A a; chỉ thực hiện một lần. Phạm vi của biến nằm trên phạm vi hàm f. Trường anotherObject nằm trong phân bổ đối tượng A.

Xem ví dụ với đếm:

#include <iostream> 
using namespace std; 
class AnotherObjectType {}; 

class A { 
public: 
    A(){count = 0;}; 
    int count; 
private: 
    AnotherObjectType anotherObject; 
}; 

A f(){ 
    static A a; 
    a.count++; 
    //Other things... 
    return a; 
} 

int main() { 
    // your code goes here 
    A a; 
    for (int i = 0; i < 3; i++) { 
     a = f(); 
     std::cout << "Count: " << a.count << std::endl; 
    } 
    return 0; 
} 

làm việc Ví dụ: http://ideone.com/USqeEZ

Xem thêm: http://www.learncpp.com/cpp-tutorial/811-static-member-variables/

0
void f(){ 
    /// this created in static segment - that's obviously for you 
    static A a; 
    //Other things... 
} 

class A { 
    public: 
     A(); 
    private: 
     /// anotherObject is not pointer but explicit part of A, 
     /// so it won't be created in heap or anywhere else, 
     /// but in the same memory segment as an instance of A. 
     AnotherObjectType anotherObject; 
}; 

Vì vậy, anotherObject sẽ không được ghi đè bởi vì static A a tạo một trường hợp của A trong phân đoạn tĩnh và bất kỳ trường hợp nào khác sẽ bị thèm trong các phân đoạn khác tùy thuộc vào phân đoạn bạn sẽ tạo.

+0

tại sao trừ đi mà không có giải thích trong các ý kiến? chuyện gì vậy? –

+1

Tôi đã đánh dấu bạn, vì tôi bị kích thích với "người tốt bụng" đã đánh dấu bạn mà không chỉ định tại sao ... Bạn có một vài lỗi chính tả, và mọi thứ không rõ ràng, nhưng tôi nhận được hình ảnh. –

+0

Cảm ơn rất nhiều vì đã giải thích. Và xin lỗi vì tiếng anh xấu của tôi.) –

0

Mặc dù cả hai được gọi là static, một thành viên tĩnh khác với biến cục bộ tĩnh.

Thành viên tĩnh được chia sẻ trong lớp học. Mỗi trường hợp của lớp này đều đề cập đến cùng một thành viên.

Biến cục bộ tĩnh được khởi tạo một lần và không bị hủy khi hàm trả về.

Trong mã của bạn, các thành viên không tĩnh được lưu trữ trong ví dụ aa vẫn tồn tại ngoài chức năng trả về.

1

Bộ nhớ là static hoặc động được phân bổ. Phân bổ động là những gì bạn nhận được khi phân bổ bộ nhớ trong thời gian chạy, với ví dụ newmalloc. Phân bổ tĩnh là "phần còn lại". Bộ nhớ cho các biến thành viên lớp được cấp phát với cá thể lớp, vì vậy nếu nó được cấp phát tĩnh, các thành viên kết thúc trong cùng một phần của bộ nhớ, và nếu nó được cấp phát động, các thành viên sẽ kết thúc nơi bộ nhớ động cư trú. Điều này cũng đúng cho các biến thành viên con trỏ, nhưng bộ nhớ thực mà nó trỏ vào có thể là động (newmalloc) hoặc được cấp phát tĩnh.

int i = 0; 
int* pi = &i;  // pi points at statically allocated memory 
pi = new int(0); // pi points at dynamically allocated memory 

Vì vậy, nếu bạn có một trường hợp lớp tĩnh, bộ nhớ cho nó và các thành viên của nó là thường bố trí trong đoạn mã, nhưng đó là một chi tiết thực hiện.

Nếu thành viên là con trỏ trỏ đến bộ nhớ được cấp phát động, bộ nhớ đó sẽ là trong đó người cấp phát đã sử dụng quyết định. "Heap" là chi tiết triển khai phổ biến nhất của bộ nhớ được cấp phát động, mà bạn thường là nhận khi sử dụng newmalloc, nhưng có thể sử dụng bộ phân bổ tùy chỉnh điều khiển bộ nhớ ở nơi khác, ngay cả trong đoạn mã.

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