โครงสร้าง C / C ++ เทียบกับคลาส


109

หลังจากจบคลาส C ++ สำหรับฉันแล้วโครงสร้าง / คลาสแทบจะเหมือนกันยกเว้นมีความแตกต่างเล็กน้อยเล็กน้อย

ฉันไม่เคยตั้งโปรแกรมใน C มาก่อน แต่ฉันรู้ว่ามันมีโครงสร้าง ใน C เป็นไปได้ไหมที่จะสืบทอดโครงสร้างอื่น ๆ และตั้งค่าตัวปรับแต่งของสาธารณะ / ส่วนตัว?

ถ้าคุณทำได้ใน C ปกติทำไมเราถึงต้องการ C ++ ในโลกนี้? อะไรทำให้คลาสแตกต่างจากโครงสร้าง?

c++  class  struct 

เป็นไปได้ที่จะทำสำเนาstackoverflow.com/questions/54585/…
gonzobrains

คำตอบ:


149

ใน C ++โครงสร้างและคลาสจะเหมือนกันมาก ข้อแตกต่างเพียงอย่างเดียวคือโดยที่ตัวแก้ไขการเข้าถึง (สำหรับตัวแปรสมาชิกวิธีการและคลาสพื้นฐาน) ในคลาสเริ่มต้นเป็นส่วนตัวตัวปรับการเข้าถึงในโครงสร้างเริ่มต้นเป็นสาธารณะ

อย่างไรก็ตามใน Cโครงสร้างเป็นเพียงการรวบรวมข้อมูล (สาธารณะ) โดยรวมและไม่มีคุณสมบัติอื่น ๆ ที่เหมือนคลาส: ไม่มีเมธอดไม่มีตัวสร้างไม่มีคลาสฐาน ฯลฯ แม้ว่า C ++ จะสืบทอดคีย์เวิร์ด แต่ก็ขยายความหมาย (อย่างไรก็ตามนี่คือสาเหตุที่สิ่งต่าง ๆ เริ่มต้นเป็นสาธารณะในโครงสร้าง - โครงสร้างที่เขียนเหมือนโครงสร้าง C จะทำงานเหมือนกัน)

แม้ว่าจะเป็นไปได้ที่จะปลอม OOP บางส่วนใน C ตัวอย่างเช่นการกำหนดฟังก์ชันที่ใช้ตัวชี้ไปยังโครงสร้างเป็นพารามิเตอร์แรกหรือในบางครั้งก็บังคับให้โครงสร้างที่มีฟิลด์สองสามช่องแรกเหมือนกันเป็น ยึดติดและไม่ได้เป็นส่วนหนึ่งของภาษาจริงๆ


จาก OOP ผู้มุ่งหวัง. Net ได้กำหนดไว้ในลักษณะนี้ ✓ CONSIDER กำหนดโครงสร้างแทนคลาสหากอินสแตนซ์ของประเภทมีขนาดเล็กและมีอายุสั้นหรือมักฝังอยู่ในวัตถุอื่น X หลีกเลี่ยงการกำหนดโครงสร้างเว้นแต่ว่าประเภทนั้นจะมีลักษณะดังต่อไปนี้ทั้งหมด: 1. มันแสดงถึงค่าเดียวในเชิงตรรกะคล้ายกับประเภทดั้งเดิม (int, double ฯลฯ ) 2. มีขนาดอินสแตนซ์ต่ำกว่า 16 ไบต์ 3. มันไม่เปลี่ยนรูป
Abhijeet

5
@ Abhijeet นั่นคือความแตกต่างระหว่างโครงสร้างและคลาสใน C # แต่นั่นไม่เกี่ยวข้องกับ C ++ และยิ่งไปกว่านั้นสำหรับ C ใน C # คลาสและโครงสร้างนั้นแตกต่างกันจริงๆ ไม่เป็นเช่นนั้นใน C ++ และ C มีโครงสร้างที่ไม่มี OO เท่านั้น
Antal Spector-Zabusky

จะไม่เป็นการดีกว่าที่จะรักษาความหมาย C เดียวกันไว้ในโครงสร้าง C ++? และเมื่อจำเป็นต้องใช้ "struct ในวิธี c ++" เพียงแค่ใช้คลาส? ฉันไม่เคยได้รับประโยชน์จากการมีโครงสร้าง "เสริม" ใน C ++ เมื่อเทียบกับ C ฉันชอบที่ยังคงใช้โครงสร้างตามที่ออกแบบใน C มิฉะนั้นให้ใช้คลาสโดยมีข้อยกเว้นบางประการที่อนุญาต
Raffaello

15

อื่น ๆ ที่ความแตกต่างในการเข้าถึงเริ่มต้น (สาธารณะ / ส่วนตัว) ไม่มีความแตกต่าง

อย่างไรก็ตามร้านค้าบางแห่งที่เขียนโค้ดใน C และ C ++ จะใช้ "class / struct" เพื่อระบุว่าสามารถใช้ได้ใน C และ C ++ (struct) และเป็น C ++ เท่านั้น (คลาส) กล่าวอีกนัยหนึ่งในรูปแบบนี้โครงสร้างทั้งหมดต้องทำงานร่วมกับ C และ C ++ นี่เป็นสาเหตุที่ทำให้เกิดความแตกต่างในครั้งแรกเมื่อนานมาแล้วย้อนกลับไปเมื่อ C ++ ยังรู้จักกันในชื่อ "C with Classes"

โปรดทราบว่าสหภาพ C ทำงานร่วมกับ C ++ แต่ไม่ใช่วิธีอื่น ตัวอย่างเช่น

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

และเช่นเดียวกัน

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

ใช้ได้เฉพาะใน C


9
การใช้คำหลัก cpp ในรหัส c ของคุณแล้วอ้างว่าไม่เข้ากันได้กับ cpp นั้นค่อนข้างโง่
Dani

10

ฉันจะเพิ่มคำตอบที่มีอยู่เพราะตอนนี้C ++ สมัยใหม่เป็นสิ่งสำคัญและได้สร้างแนวทางหลักอย่างเป็นทางการเพื่อช่วยในการตอบคำถามเช่นนี้

นี่คือส่วนที่เกี่ยวข้องจากหลักเกณฑ์:

C.2: ใช้คลาสถ้าคลาสมีค่าคงที่ ใช้โครงสร้างหากสมาชิกข้อมูลสามารถเปลี่ยนแปลงได้อย่างอิสระ

ค่าคงที่เป็นเงื่อนไขทางตรรกะสำหรับสมาชิกของอ็อบเจ็กต์ที่คอนสตรัคเตอร์ต้องสร้างขึ้นเพื่อให้ฟังก์ชันสมาชิกสาธารณะถือว่า หลังจากสร้างค่าคงที่แล้ว (โดยทั่วไปโดยตัวสร้าง) ทุกฟังก์ชันของสมาชิกสามารถเรียกใช้สำหรับอ็อบเจ็กต์ได้ ค่าคงที่สามารถระบุได้อย่างไม่เป็นทางการ (เช่นในความคิดเห็น) หรือมากกว่านั้นอย่างเป็นทางการโดยใช้ Expects

หากสมาชิกข้อมูลทั้งหมดสามารถแตกต่างกันไปโดยไม่ขึ้นกับกันก็จะไม่มีค่าคงที่เป็นไปได้

หากคลาสมีข้อมูลส่วนตัวผู้ใช้จะไม่สามารถเริ่มต้นอ็อบเจ็กต์ได้อย่างสมบูรณ์โดยไม่ต้องใช้คอนสตรัคเตอร์ ดังนั้นตัวกำหนดคลาสจะให้ตัวสร้างและต้องระบุความหมาย นี่หมายถึงความจำเป็นที่แน่นอนในการกำหนดค่าคงที่

การบังคับใช้

มองหาโครงสร้างที่มีข้อมูลส่วนตัวและคลาสที่มีสมาชิกสาธารณะ

ตัวอย่างโค้ดที่ให้:

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
};

Classes ทำงานได้ดีสำหรับสมาชิกที่มาจากกันและกันหรือสัมพันธ์กัน นอกจากนี้ยังสามารถช่วยในการตรวจสอบสติสัมปชัญญะเมื่อมีการสร้างอินสแตนซ์ Structทำงานได้ดีกับการมี "ถุงข้อมูล" โดยที่ไม่มีอะไรพิเศษเกิดขึ้นจริง ๆ แต่สมาชิกก็มีเหตุผลที่จะรวมกลุ่มกัน

จากสิ่งนี้ทำให้รู้สึกว่าclassมีอยู่เพื่อรองรับการห่อหุ้มและแนวคิดการเข้ารหัสอื่น ๆ ที่เกี่ยวข้องซึ่งstructไม่มีประโยชน์มากนักสำหรับ


ข้อควรพิจารณาอีกประการหนึ่งคือการพกพา structs เป็นแบบพกพามากที่สุด สามารถใช้โดย C หรือ C ++ หรือกลับไปกลับมา นอกจากนี้ยังสามารถแตกไฟล์ใน Python โดยใช้structโมดูลได้เช่นกัน ถ้าจัดลำดับความสำคัญโครงการของคุณถูกใช้งานร่วมกับภาษาอื่น ๆ อินเตอร์เฟซหรือระบบชอบมากกว่าstruct สำหรับกิจการอย่างเคร่งครัดโปรแกรมภายในต้องการclass class
Dave

6

ไม่สามารถกำหนดฟังก์ชันสมาชิกหรือรับโครงสร้างจากกันและกันใน C

นอกจากนี้ C ++ ไม่ได้เป็นเพียง C + "derive structs" เท่านั้น เทมเพลตการอ้างอิงเนมสเปซที่ผู้ใช้กำหนดและตัวดำเนินการที่โอเวอร์โหลดทั้งหมดไม่มีอยู่ใน C


ฉันรู้ว่าแม่แบบ ฯลฯ ที่จะไม่มีอยู่ใน C แต่ฉันไม่ทราบถึงpowerโครงสร้างใน C ดังนั้น C ++ จึงใช้เพียงโครงสร้างเพื่อให้ 'ถอยหลัง' เข้ากันได้กับ C?

4
เพียงเพื่อความเข้ากันได้ย้อนหลัง? ในทางปฏิบัติอาจมีบางอย่างสำหรับสิ่งนั้น แต่ความแตกต่างอาจเป็นสัญญาณของเจตนา: โดยที่ฉันใช้structI หมายถึงประเภทของสิ่งที่เป็น Passive POD เป็นส่วนใหญ่
dmckee --- อดีตผู้ดูแลลูกแมว

@dmckee: สำหรับสิ่งที่คุ้มค่า functors STL ส่วนใหญ่ (เช่นstd::less) ถูกกำหนดให้เป็นโครงสร้างไม่ใช่คลาส
Billy ONeal

1
C ++ ไม่สามารถใช้แบ็คเอนด์กับ C ได้อย่างสมบูรณ์คุณสามารถพูดได้ว่าคีย์เวิร์ด struct เป็นที่พักสำหรับนักพัฒนา C ฉันชอบคีย์เวิร์ด struct สำหรับคลาสที่เก็บข้อมูลตามลำดับ แต่ไม่ได้ให้ตรรกะ (มาก) ด้วยตัวเอง
ypnos

@ypnos: ดูความคิดเห็นล่าสุดของฉัน ข้อแตกต่างเพียงอย่างเดียวระหว่างสองสมาชิกคือสมาชิกเริ่มต้นเป็นสาธารณะและอีกคนเป็นค่าเริ่มต้นส่วนตัว
Billy ONeal

3

ความแตกต่างอีกอย่างหนึ่งใน C ++ เมื่อคุณสืบทอดคลาสจากโครงสร้างโดยไม่มีตัวระบุการเข้าถึงใด ๆ มันจะกลายเป็นมรดกสาธารณะโดยที่ในกรณีของคลาสเป็นการสืบทอดส่วนตัว


1

C ++ ใช้โครงสร้างเป็นหลักสำหรับ 1) ความเข้ากันได้ย้อนหลังกับ C และ 2) ประเภท POD โครงสร้าง C ไม่มีวิธีการสืบทอดหรือการมองเห็น


2
สำหรับสิ่งที่คุ้มค่า functors STL ส่วนใหญ่ (กล่าวคือstd::less) ถูกกำหนดให้เป็นโครงสร้างไม่ใช่คลาส
Billy ONeal

3
โปรดทราบว่าโครงสร้าง C ++ มีวิธีการสืบทอดและการมองเห็น
robertwb

โครงสร้าง c สามารถรวมตัวชี้ฟังก์ชันได้แม้ว่าจะเป็นประเภท (* addr) (พารามิเตอร์);
ข้อผิดพลาด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.