2012-03-05 30 views
7

Tôi là một người mới bắt đầu với C++, tôi đã có những đoạn mã sau đây:C++: struct và mới từ khóa

struct Airline { 
    string Name; 
    int diameter; 
    int weight; 
}; 

Airline* myPlane = new Airline; 

câu hỏi của tôi là khi tôi gọi phương thức new nó cấp phát bộ nhớ, nếu tôi nhớ đúng. Làm thế nào để máy tính biết bao nhiêu bộ nhớ để phân bổ, đặc biệt là cho rằng có một loại chuỗi trong đó?

Cảm ơn

+0

phỏng đoán của tôi, không biết C++, là nó chỉ lưu trữ một con trỏ tới chuỗi có nội dung thực sự ở đâu đó trong heap. –

Trả lời

12

Một đối tượng std::string có kích thước cố định; nó chứa một con trỏ đến một bộ đệm thực của các ký tự cùng với độ dài của nó. định nghĩa std::string 's trông giống như

class string 
{ 
    char *buffer; 
    size_t nchars; 

    public: 
    // interface 
}; 

Nó sau đó Airline đối tượng của bạn cũng có một kích thước cố định.

Hiện tại, new không chỉ phân bổ; nó cũng khởi tạo đối tượng của bạn, bao gồm cả std::string, có nghĩa là nó có thể đặt con trỏ char thành 0 vì chuỗi đó trống.

+0

Cảm ơn. Điều này xóa nó lên. – Dan

0

Khi bạn phân bổ Airline, new sẽ phân bổ đủ không gian trên heap cho hai ints, string và các lĩnh vực của mình.

A string sẽ luôn có cùng kích thước trên ngăn xếp. Tuy nhiên, nội bộ, các string lưu trữ một con trỏ đến một mảng ký tự.

+0

Bạn có thể muốn thêm * nơi * phân bổ mới và cách trả lại liên quan mới đến vị trí đó. –

0

Bộ nhớ cho chuỗi có thể hoặc không nằm trong lớp string. Có thể (và có thể), lớp string sẽ quản lý bộ nhớ riêng của nó, chỉ có một con trỏ đến bộ nhớ được sử dụng để lưu trữ dữ liệu. Ví dụ:

struct Airlane { 
    String Name { 
     char *data; // size = 4 
     size_t size; // size = 4 
    } 
    int diameter; // size = 4 
    int weight; // size = 4 
}; // size = 16 

Lưu ý rằng những thứ đó không nhất thiết là kích thước thực, chúng chỉ là ví dụ.

Cũng lưu ý rằng trong C++ (không giống như C, ví dụ), cho mỗi class T, sizeof T là hằng số thời gian biên dịch, có nghĩa là các đối tượng không bao giờ có kích thước động. Điều này có nghĩa là: Ngay sau khi bạn cần dữ liệu có kích thước động thời gian chạy, phải có các vùng nhớ bên ngoài (w.r.t. the object). Điều này có thể ngụ ý việc sử dụng các vùng chứa tiêu chuẩn như std::string hoặc std::vector hoặc thậm chí tài nguyên được quản lý theo cách thủ công.

Điều này có nghĩa là, operator new không cần biết kích thước động của tất cả các thành viên, đệ quy, mà chỉ là kích thước của lớp ngoài cùng, thứ mà bạn phân bổ. Khi lớp bên ngoài này cần nhiều bộ nhớ hơn, nó phải tự quản lý nó. Một số gương mẫu p-code:

Airline* myPlane = new Airline { 
    Name = { 
     data = new char[some-size] 
     ... 
    } 
    ... 
} 

Các phân bổ bên trong được thực hiện bởi các nhà thầu nắm giữ:

Airline::Airline() : string(), ... {} 
string::string() : data(new char[...] ... {} 

operator new không có gì khác, nhưng để phân bổ một số bộ nhớ kích thước cố định là "đất" cho Airline (xem p-code đầu tiên) và sau đó là "seed" Airline s constructor, chính nó phải quản lý tuổi thọ của nó trong khối lượng "đất" bị giới hạn, bằng cách gọi hàm tạo chuỗi (ngầm hoặc rõ ràng), chính nó thực hiện một số khác new.

2

Bạn cũng có thể nhận được kích thước của cấu trúc, bằng cách sử dụng sizeof:

cout << "sizeof(Airline) = " << sizeof(Airline) << endl; 

Điều này là do trình biên dịch biết các lĩnh vực bên trong cấu trúc, và cho biết thêm lên các kích thước của mỗi thành viên cấu trúc.

Đối tượng string không khác với cấu trúc của bạn. Nó thực sự là một lớp trong thư viện chuẩn, và không phải là một kiểu đặc biệt như int hoặc float được trình biên dịch xử lý. Giống như cấu trúc của bạn, lớp string chứa các trường mà trình biên dịch biết kích thước của và vì vậy nó biết kích thước của cấu trúc hoàn chỉnh của bạn và sử dụng nó khi bạn sử dụng new.

2

Cuộc gọi đến new sẽ phân bổ sizeof(Airline) đó là những gì cần thiết để giữ một đối tượng thuộc loại Airline.

Khi quản lý chuỗi, đối tượng string giữ một số dữ liệu nội bộ để quản lý bộ nhớ của dữ liệu thực được lưu trữ, chứ không phải chính dữ liệu (trừ khi tối ưu hóa đối tượng nhỏ đang được sử dụng). Trong khi ý tưởng giống với ý tưởng được người khác trỏ đến bằng lưu con trỏ vào chuỗi thực tế, không đủ chính xác vì triển khai sẽ lưu trữ con trỏ đó cùng với dữ liệu bổ sung cần có để giữ size()capacity() (và các loại khác, giống như số tham chiếu trong việc triển khai tính tham chiếu).

+0

giải thích tuyệt vời. Cảm ơn nhiều. – Dan

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