มิกซินด้วย CRTP
ประกอบพฤติกรรมขณะคอมไพล์
มิกซินด้วย CRTP เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
มิกซ์อินคืออะไร
มิกซ์อิน คือหน่วยพฤติกรรมขนาดเล็กที่นำกลับมาใช้ใหม่ได้ และนำมาประกอบเข้ากับคลาส ด้วย CRTP มิกซ์อินจะเพิ่มความสามารถขณะคอมไพล์ พร้อมทั้งยังเรียกใช้คลาสเจ้าของได้
มิกซ์อินอย่างง่าย
มิกซ์อินนี้เพิ่มฟังก์ชันสมาชิก print_twice ซึ่งต้องอาศัยคลาสเจ้าของที่มี value()
#include <iostream>
template <typename T>
struct PrintTwice {
void print_twice() const {
auto v = static_cast<const T*>(this)->value();
std::cout << v << " " << v << "\n";
}
};
struct Box : PrintTwice<Box> {
int value() const { return 7; }
};
int main() {
Box{}.print_twice();
return 0;
}การประกอบมิกซ์อินหลายรายการ
คุณสามารถสืบทอดจากมิกซ์อิน CRTP หลายรายการพร้อมกัน เพื่อซ้อนพฤติกรรมที่เป็นอิสระต่อกันไว้ในคลาสเดียว
#include <iostream>
template <typename T>
struct Loggable {
void log() const { std::cout << "log: " << static_cast<const T*>(this)->id() << "\n"; }
};
template <typename T>
struct Resettable {
void reset() { static_cast<T*>(this)->set(0); }
};
struct Device : Loggable<Device>, Resettable<Device> {
int v = 5;
int id() const { return v; }
void set(int x) { v = x; }
};
int main() {
Device d;
d.log();
d.reset();
d.log();
return 0;
}มิกซ์อินเพิ่มสถานะได้เช่นกัน
มิกซ์อินสามารถมีสมาชิกข้อมูลของตนเอง ซึ่งจะกลายเป็นส่วนหนึ่งของโครงสร้างหน่วยความจำของออบเจ็กต์ที่ประกอบขึ้น
#include <iostream>
template <typename T>
struct Tagged {
int tag = 0;
void set_tag(int t) { tag = t; }
int get_tag() const { return tag; }
};
struct Item : Tagged<Item> {
const char* name = "item";
};
int main() {
Item it;
it.set_tag(42);
std::cout << it.name << " " << it.get_tag() << "\n";
return 0;
}มิกซ์อินกับการสืบทอดทั่วไป
มิกซ์อิน CRTP แตกต่างจากการสืบทอดทั่วไป เพราะฐานสามารถเรียกย้อนลงไปยังคลาสสืบทอดได้ คลาสฐานทั่วไปไม่สามารถเรียกฟังก์ชันสมาชิกที่มีอยู่เฉพาะในประเภทสืบทอดได้ หากไม่มีฟังก์ชันเสมือน
การออกแบบตามนโยบาย
มิกซ์อินทำให้เกิดการออกแบบตามนโยบาย กล่าวคือเลือกพฤติกรรมขณะคอมไพล์ด้วยการเลือกว่าจะสืบทอดจากมิกซ์อินใด คล้ายกับที่ std::vector รับนโยบายตัวจัดสรร
ลำดับและโครงสร้างหน่วยความจำ
เมื่อซ้อนมิกซ์อิน ลำดับของฐานจะส่งผลต่อลำดับการสร้างและโครงสร้างหน่วยความจำของออบเจ็กต์ ควรทำให้มิกซ์อินเป็นอิสระต่อกัน เพื่อให้ลำดับไม่ส่งผลต่อความถูกต้อง
- สร้างตามลำดับการประกาศฐาน
- หลีกเลี่ยงมิกซ์อินที่ต้องพึ่งพากัน
การเพิ่มมิกซ์อินความเท่ากัน
ในตัวอย่างนี้ มิกซ์อินจะสร้าง operator!= จากการตรวจสอบความเท่ากันของคลาสเจ้าของ
#include <iostream>
template <typename T>
struct EqualityMixin {
friend bool operator!=(const T& a, const T& b) { return !(a == b); }
};
struct P : EqualityMixin<P> {
int x;
P(int v) : x(v) {}
friend bool operator==(const P& a, const P& b) { return a.x == b.x; }
};
int main() {
std::cout << (P(1) != P(2)) << "\n";
return 0;
}มิกซ์อินแบบมีเงื่อนไข
คุณสามารถใส่มิกซ์อินเฉพาะเมื่อเงื่อนไขเป็นจริงได้ โดยผสานการสืบทอดเข้ากับ std::conditional เพื่อเลือกมิกซ์อินจริงหรือมิกซ์อินว่าง
การปรับให้ฐานว่างมีประสิทธิภาพ
มิกซ์อินที่ไม่มีสมาชิกข้อมูลจะได้รับประโยชน์จาก การปรับให้ฐานว่างมีประสิทธิภาพ โดยคอมไพเลอร์จะไม่จัดสรรไบต์เพิ่มเติมให้เลย ดังนั้นการซ้อนมิกซ์อินไร้สถานะจำนวนมากจึงไม่เพิ่มขนาดออบเจ็กต์
#include <iostream>
template <typename T>
struct A {};
template <typename T>
struct B {};
struct C : A<C>, B<C> {
int x;
};
int main() {
std::cout << (sizeof(C) == sizeof(int)) << "\n";
return 0;
}ควรเลือกใช้มิกซ์อินเมื่อใด
มิกซ์อินเหมาะอย่างยิ่งเมื่อหลายคลาสต้องการพฤติกรรมที่แยกจากกันชุดเดียวกัน เช่น การบันทึกข้อมูล การนับ และการเปรียบเทียบ มิกซ์อินช่วยรวมพฤติกรรมแต่ละอย่างไว้ในที่เดียว และนำมาประกอบกันได้โดยไม่มีค่าใช้จ่ายขณะทำงาน
ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจของคุณเกี่ยวกับมิกซ์อิน CRTP
สรุปทบทวน
คุณได้เรียนรู้การสร้างมิกซ์อินด้วย CRTP
- มิกซ์อินประกอบพฤติกรรมที่แยกจากกันขณะคอมไพล์
- มิกซ์อินสามารถเรียกย้อนลงไปยังคลาสเจ้าของและเก็บสถานะได้
- มิกซ์อินไร้สถานะไม่เพิ่มขนาดเนื่องจากการปรับให้ฐานว่างมีประสิทธิภาพ
- เหมาะอย่างยิ่งสำหรับนโยบายการบันทึกข้อมูล การเปรียบเทียบ และการนับ
คำถามที่พบบ่อย
บทเรียน “มิกซินด้วย CRTP” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “มิกซินด้วย CRTP” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “มิกซินด้วย CRTP”
ประกอบพฤติกรรมขณะคอมไพล์ คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “มิกซินด้วย CRTP” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- สำนวน CRTP
- พหุรูปแบบแบบคงที่
- มิกซินด้วย CRTP
- เมื่อใดควรใช้ CRTP