C / C ++ Struct so với Class


108

Sau khi học xong lớp C ++, đối với tôi, dường như các cấu trúc / lớp hầu như giống hệt nhau ngoại trừ một vài khác biệt nhỏ.

Tôi chưa bao giờ lập trình bằng C trước đây; nhưng tôi biết rằng nó có cấu trúc. Trong C có thể kế thừa các cấu trúc khác và đặt bổ ngữ là public / private không?

Nếu bạn có thể làm điều này trong C thông thường tại sao trên thế giới chúng ta cần C ++? Điều gì làm cho các lớp khác với một cấu trúc?

c++  class  struct 


Câu trả lời:


146

Trong C ++ , cấu trúc và lớp khá giống nhau; sự khác biệt duy nhất là nơi các sửa đổi truy cập (cho các biến thành viên, phương thức và lớp cơ sở) trong các lớp được mặc định là private, các sửa đổi truy cập trong cấu trúc được mặc định là public.

Tuy nhiên, trong C , một cấu trúc chỉ là một tập hợp tổng hợp dữ liệu (công khai) và không có các tính năng giống lớp khác: không có phương thức, không có hàm tạo, không có lớp cơ sở, v.v. Mặc dù C ++ kế thừa từ khóa, nhưng nó đã mở rộng ngữ nghĩa. (Tuy nhiên, đây là lý do tại sao mọi thứ được mặc định là công khai trong cấu trúc — một cấu trúc được viết như cấu trúc C hoạt động giống như một cấu trúc.)

Mặc dù có thể giả mạo một số OOP trong C — chẳng hạn, việc xác định các hàm đều lấy một con trỏ đến một cấu trúc làm tham số đầu tiên của chúng hoặc đôi khi ép buộc các cấu trúc có cùng một vài trường đầu tiên thành "sub / superclass" —nó luôn là bắt đầu và không thực sự là một phần của ngôn ngữ.


Từ OOP triển vọng .Net kẻ đã định nghĩa nó theo cách này ✓ CONSIDER xác định một cấu trúc thay vì một lớp nếu các thể hiện của loại này nhỏ và thường tồn tại trong thời gian ngắn hoặc thường được nhúng trong các đối tượng khác. X TRÁNH việc xác định một cấu trúc trừ khi kiểu có tất cả các đặc điểm sau: 1. Nó đại diện một cách hợp lý cho một giá trị duy nhất, tương tự như các kiểu nguyên thủy (int, double, v.v.). 2. Nó có kích thước cá thể dưới 16 byte. 3. Nó là bất biến.
Abhijeet

5
@Abhijeet Đó là sự phân biệt giữa cấu trúc và lớp trong C #, nhưng điều đó chỉ đơn giản là không liên quan đến C ++, và thậm chí còn hơn thế nữa đối với C. Trong C #, các lớp và cấu trúc thực sự khác nhau; không phải như vậy trong C ++ và C chỉ có cấu trúc mà không có OO.
Antal Spector-Zabusky

Sẽ không tốt hơn nếu giữ cùng một ngữ nghĩa C trong cấu trúc C ++? và khi được yêu cầu sử dụng "struct theo cách c ++" chỉ cần sử dụng một lớp? Tôi chưa bao giờ nhận được lợi ích của việc có cấu trúc "tăng cường" trong C ++ so với C. Tôi vẫn thích sử dụng cấu trúc như nơi được thiết kế trong C, nếu không hãy sử dụng một lớp, với một số ngoại lệ được phép.
Raffaello

15

Khác rằng sự khác biệt trong quyền truy cập mặc định (công khai / riêng tư), không có sự khác biệt.

Tuy nhiên, một số cửa hàng viết mã bằng C và C ++ sẽ sử dụng "class / struct" để chỉ ra rằng cái nào có thể được sử dụng trong C và C ++ (struct) và chỉ là C ++ (lớp). Nói cách khác, theo phong cách này, tất cả các cấu trúc phải hoạt động với C và C ++. Đây là lý do tại sao có sự khác biệt ngay từ đầu từ rất lâu trước đây, khi C ++ vẫn được gọi là "C với các lớp."

Lưu ý rằng C union hoạt động với C ++, nhưng không phải ngược lại. Ví dụ

union WorksWithCppOnly{
    WorksWithCppOnly():a(0){}
    friend class FloatAccessor;
    int a;
private:
    float b;
};

Và tương tự

typedef union friend{
    int a;
    float b;
} class;

chỉ hoạt động ở C


9
Sử dụng từ khóa cpp trong mã c của bạn và sau đó tuyên bố nó không được CPP tương thích là khá ngu ngốc
Dani

7

Tôi sẽ thêm vào các câu trả lời hiện có bởi vì C ++ hiện đại giờ đã trở thành một thứ và các Nguyên tắc cốt lõi chính thức đã được tạo ra để trợ giúp các câu hỏi như thế này.

Đây là một phần có liên quan từ các nguyên tắc:

C.2: Sử dụng lớp nếu lớp có một bất biến; sử dụng struct nếu các thành viên dữ liệu có thể khác nhau một cách độc lập

Một bất biến là một điều kiện logic cho các thành viên của một đối tượng mà một phương thức khởi tạo phải thiết lập để các chức năng thành viên chung đảm nhận. Sau khi bất biến được thiết lập (thường là bởi một phương thức khởi tạo), mọi hàm thành viên đều có thể được gọi cho đối tượng. Một bất biến có thể được nêu một cách không chính thức (ví dụ: trong một bình luận) hoặc chính thức hơn bằng cách sử dụng Kỳ vọng.

Nếu tất cả các thành viên dữ liệu có thể thay đổi độc lập với nhau, thì không thể bất biến.

Nếu một lớp có bất kỳ dữ liệu riêng tư nào, người dùng không thể khởi tạo hoàn toàn một đối tượng mà không sử dụng hàm tạo. Do đó, trình định nghĩa lớp sẽ cung cấp một phương thức khởi tạo và phải chỉ rõ ý nghĩa của nó. Điều này có nghĩa là trình định nghĩa cần xác định một bất biến.

Thực thi

Tìm kiếm cấu trúc với tất cả dữ liệu riêng tư và các lớp có thành viên công khai.

Các ví dụ mã được đưa ra:

struct Pair {  // the members can vary independently
    string name;
    int volume;
};

// but

class Date {
public:
    // validate that {yy, mm, dd} is a valid date and initialize
    Date(int yy, Month mm, char dd);
    // ...
private:
    int y;
    Month m;
    char d;    // day
};

Classchúng hoạt động tốt cho các thành viên, ví dụ, có nguồn gốc từ nhau hoặc có liên quan với nhau. Họ cũng có thể giúp kiểm tra sự tỉnh táo khi bắt đầu. Structs hoạt động tốt vì có "túi dữ liệu", nơi không có gì đặc biệt thực sự đang diễn ra nhưng các thành viên sẽ hợp lý khi được nhóm lại với nhau.

Từ đó, có thể hiểu rằng các classes tồn tại để hỗ trợ việc đóng gói và các khái niệm mã hóa liên quan khác, những khái niệm đó structđơn giản là không hữu ích cho lắm.


Một cân nhắc khác là tính di động. structs là di động nhất. Chúng có thể được sử dụng bởi C hoặc C ++ hoặc qua lại. structVí dụ: chúng cũng có thể được giải nén bằng Python bằng cách sử dụng mô-đun. Nếu dự án của bạn ưu tiên tương thích với các ngôn ngữ, giao diện hoặc hệ thống khác, hãy ưu tiên structhơn class. Đối với các vấn đề nội bộ nghiêm ngặt, thích class.
Dave

6

Không thể xác định các hàm thành viên hoặc lấy cấu trúc từ nhau trong C.

Ngoài ra, C ++ không chỉ là C + "dẫn xuất cấu trúc". Các mẫu, tham chiếu, không gian tên do người dùng xác định và nạp chồng toán tử đều không tồn tại trong C.


Tôi biết rằng các mẫu, v.v. không tồn tại trong C nhưng tôi không biết powervề cấu trúc trong C. Vì vậy, sau đó C ++ chỉ sử dụng cấu trúc để tương thích 'ngược' với C?

4
Chỉ để tương thích ngược? Trên cơ sở thực tế, có thể có điều gì đó xảy ra, nhưng sự khác biệt có thể là một tín hiệu của ý định: nơi tôi sử dụng structý tôi là một loại POD chủ yếu thụ động.
dmckee --- ex-moderator kitten

@dmckee: Đối với những gì nó đáng giá, hầu hết các chức năng STL (tức là std::less) được định nghĩa là cấu trúc, không phải lớp.
Billy ONeal

1
C ++ không hoàn toàn tương thích với C. Bạn có thể nói rằng từ khóa struct là nơi cư trú cho các nhà phát triển C. Tôi thích từ khóa struct cho các lớp chỉ giữ dữ liệu theo kiểu có thứ tự nhưng không cung cấp (nhiều) logic.
ypnos

@ypnos: Xem bình luận cuối cùng của tôi. Sự khác biệt duy nhất giữa cả hai là các thành viên của một người được mặc định là công khai, và thành viên còn lại là riêng tư mặc định.
Billy ONeal

3

Một điểm khác biệt nữa trong C ++, khi bạn kế thừa một lớp từ struct mà không có bất kỳ chỉ định truy cập nào, nó sẽ trở thành kế thừa công khai, trong trường hợp lớp đó là kế thừa riêng.


1

C ++ sử dụng cấu trúc chủ yếu cho 1) tương thích ngược với C và 2) các loại POD. Cấu trúc C không có phương thức, kế thừa hoặc khả năng hiển thị.


2
Đối với những gì nó đáng giá, hầu hết các chức năng STL (tức là std::less) được định nghĩa là cấu trúc, không phải lớp.
Billy ONeal

3
Lưu ý rằng cấu trúc C ++ có các phương thức, kế thừa và khả năng hiển thị.
robertwb

c struct có thể bao gồm con trỏ hàm như kiểu (* addr) (params);
Lỗi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.