2009-11-16 54 views
5

Loại C++ nào có thể được khởi tạo?Điều gì có thể được khởi tạo?

Tôi biết rằng sau mỗi trực tiếp tạo ra một trường hợp duy nhất của Foo:

Foo bar; 
Foo *bizz = new Foo(); 

Tuy nhiên, những gì về với built-in loại? Có phải sau đây tạo ra hai trường hợp của int, hoặc là ví dụ từ sai để sử dụng và bộ nhớ chỉ được phân bổ?

int bar2; 
int *bizz2 = new int; 

Còn con trỏ thì sao? Ví dụ trên có tạo ra một cá thể int * hoặc chỉ cấp phát bộ nhớ cho một int * không?

Có sử dụng các literals như 42 hoặc 3.14 cũng tạo một cá thể không?

Tôi đã nhìn thấy đối số rằng nếu bạn không thể phân loại một loại, nó không phải là một lớp, và nếu nó không phải là một lớp, nó không thể được khởi tạo. Điều này có đúng không?

Trả lời

4

Miễn là chúng ta đang nói về C++, nguồn có thẩm quyền duy nhất là tiêu chuẩn ISO. Điều đó không bao giờ sử dụng từ "instantiation" cho bất cứ điều gì ngoài các lớp và các mẫu chức năng.

Tuy nhiên, sử dụng từ "thể hiện". Ví dụ:

Ví dụ của từng đối tượng có thời lượng lưu trữ tự động (3.7.2) được liên kết với mỗi mục nhập vào khối của nó.

Lưu ý rằng trong C++ cách nói, một giá trị trái int cũng là một "đối tượng":

Các cấu trúc trong một chương trình C++ tạo, phá hủy, hãy tham khảo, truy cập và thao tác các đối tượng. Một đối tượng là một vùng lưu trữ.

Kể từ khi new tạo rõ ràng vùng lưu trữ, bất kỳ thứ gì được tạo ra là một đối tượng và theo tiền lệ của đặc tả, có thể được gọi là một thể hiện.

+0

Rất hay. Cảm ơn. =] – strager

+0

Đây có lẽ là câu trả lời hay nhất cho đến nay. Sự khác biệt giữa tiêu chuẩn C++ và thuật ngữ OOP chung rất thú vị. Hầu hết các lập trình viên OOP có lẽ sẽ không gọi một cái gì đó giống như 'int x' một thể hiện của một' int', cũng không phải họ có thể tham chiếu đến một 'int' như một đối tượng; nhưng dù sao nó cũng đúng về mặt kỹ thuật để chỉ nó như vậy. –

+1

Có, "trường hợp" được trích dẫn bởi Pavel không được sử dụng ở tất cả trong ý nghĩa OOP thông thường, vì nó nói "trường hợp của một đối tượng", không phải "trường hợp của một loại". Tôi nghĩ rằng nó có thể được thay thế bằng "một đối tượng khác với ..." và có nghĩa là điều tương tự. Tôi suy đoán hầu hết các lập trình viên OOP sẽ không tham chiếu đến một int như một đối tượng bởi vì chúng được huấn luyện trên Java, nơi mà thực sự một 'int' không phải là một' Object'. Các ngôn ngữ OOP purer không tạo ngoại lệ cho các kiểu dựng sẵn, do đó các số nguyên của chúng là các đối tượng. Trong Ruby, bạn có thể tự động cập nhật các phương thức monkey-class cho lớp đại diện cho chúng, để làm cho '3.minutes' bằng 180. –

2

trong C++ một 'dụ' và 'thuyết minh' chỉ được kết hợp với lớp

lưu ý tuy nhiên đó đây cũng là những từ tiếng Anh mà có thể có ý nghĩa đối thoại. 'con trỏ' chắc chắn là một lớp của sự vật trong việc sử dụng tiếng Anh và một con trỏ chắc chắn là một thể hiện của lớp đó

nhưng trong C++ nói 'con trỏ' không phải là một Lớp và con trỏ không phải là một thể hiện của một lớp

cũng thấy - có bao nhiêu thiên thần trên pinheads

+0

tuy nhiên có các ngôn ngữ khác (ví dụ như smalltalk) ở đó mọi thứ đều là đối tượng, vì vậy bạn có thể nhận được các số nguyên v.v. – pm100

+0

"trong C++ là 'instance' và 'instantiate' chỉ được liên kết với Classes" - source? –

2

Khái niệm về một "dụ" không phải là một cái gì đó thực sự bên trong C++ - về cơ bản bạn có "điều đó có một constructor và điều đó không".

Vì vậy, tất cả các loại đều có kích thước, ví dụ: một int thường là 4 byte, một cấu trúc với một vài int sẽ là 8 và cứ tiếp tục như vậy. Bây giờ, slap một constructor trên cấu trúc đó, và nó bắt đầu tìm kiếm (và hành xử) giống như một lớp. Cụ thể hơn:

int foo; // <-- 4 bytes, no constructor 

struct Foo 
{ 
    int foo; 
    int bar; 
}; // <-- 8 bytes, no constructor 

struct Foo 
{ 
    Foo() : foo(0), bar(0) {} 
    int foo; 
    int bar; 
}; // <-- 8 bytes, with constructor 

Bây giờ, bạn bất kỳ những loại có thể sống trên chồng hoặc trên đống. Khi bạn tạo thứ gì đó trên ngăn xếp , như "int foo;" ở trên, biến mất sau khi phạm vi của nó biến mất (ví dụ: ở cuối cuộc gọi hàm). Nếu bạn tạo thứ gì đó có "mới", nó sẽ được đặt trên heap và có vị trí riêng để sống trong bộ nhớ cho đến khi bạn gọi xóa trên đó. Trong cả hai trường hợp, hàm tạo, nếu có, sẽ được gọi trong quá trình khởi tạo.

1

Thật lạ khi làm "int mới", nhưng nó được cho phép. Bạn thậm chí có thể vượt qua 0 hoặc 1 đối số cho hàm tạo. Tôi không chắc chắn nếu "int mới()" có nghĩa là nó 0-initialized (tôi đoán có) là khác biệt với "int mới".

Khi bạn xác định giá trị trên ngăn xếp, nó thường không được gọi là "cấp phát bộ nhớ" (mặc dù nó đang nhận bộ nhớ trên ngăn xếp theo lý thuyết, có thể giá trị chỉ sống trong sổ đăng ký CPU).

Văn học không nhất thiết phải lấy địa chỉ trong bộ nhớ chương trình; Hướng dẫn CPU có thể mã hóa dữ liệu trực tiếp (ví dụ: đặt 42 vào thanh ghi B).Có lẽ các hằng số dấu phẩy động tùy ý có một địa chỉ.

+0

Tôi chủ yếu tìm câu trả lời nếu một 'int' và các kiểu built-in khác có thể được * instantiated *. Tôi giả sử, dựa trên câu trả lời khác và câu trả lời của bạn, một 'int' có một constructor do đó có thể có một instance, đúng không? – strager

+0

Không, int không có hàm tạo. C++ phân biệt giữa các loại POD và không phải POD, trong đó các loại POD có thể có hàm tạo, hàm thành viên, biến thành viên riêng tư, v.v. và các loại không phải POD không thể. –

+0

Cấu trúc POD có các hàm tạo. Họ không có các nhà xây dựng _non-trivial_. –

3

Theo như tôi có thể nói, bạn thực sự chỉ hỏi về thuật ngữ tại đây. Sự khác biệt duy nhất được thực hiện bởi tiêu chuẩn C++ là loại POD và các loại không POD, trong đó các loại không phải POD có các tính năng như hàm tạo do người dùng xác định, hàm thành viên, biến riêng tư, v.v. Các loại cơ bản như intfloat dĩ nhiên là POD, cũng như các mảng POD và C-cấu trúc POD.

Ngoài (và chồng chéo) C++, khái niệm "một thể hiện" trong Lập trình hướng đối tượng thường đề cập đến phân bổ không gian cho một đối tượng trong bộ nhớ, và sau đó khởi tạo nó với một hàm tạo. Cho dù điều này được thực hiện trên stack hoặc đống, hoặc bất kỳ vị trí nào khác trong bộ nhớ cho rằng vấn đề, phần lớn là không liên quan.

Tuy nhiên, chuẩn C++ dường như xem xét tất cả các loại dữ liệu "đối tượng". Ví dụ, trong 3.9 nó nói:

"Các đại diện đối tượng của loại T là dãy gồm N unsigned char đối tượng đưa lên bởi các đối tượng kiểu T, trong đó N bằng sizeof (T) .. . "

Vì vậy, về cơ bản, sự khác biệt duy nhất được thực hiện bởi chính tiêu chuẩn C++ là POD so với không phải POD.

+0

Trích dẫn tiêu chuẩn thật tuyệt vời. Cảm ơn! Trông giống như một bước đi đúng hướng. – strager

+0

Câu lệnh của bạn "Các kiểu cơ bản như' int' và 'float' dĩ nhiên không phải là POD, cũng như các mảng POD và C-cấu trúc của POD." có vẻ không chính xác. Bạn có nghĩa là để thay thế "không POD" với "POD" và ngược lại? – strager

+0

Đúng, xin lỗi - đó là lỗi đánh máy.Tôi đã chỉnh sửa bài đăng một chút và sửa lỗi đó. –

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