คำถามนี้ให้ตัวอย่างที่ชัดเจนว่าคุณสามารถใช้มาโครได้ไม่ดีอย่างไร หากต้องการดูตัวอย่างอื่น ๆ (และได้รับความบันเทิง) ให้ดูคำถามนี้
ต้องบอกว่าฉันจะให้ตัวอย่างโลกแห่งความจริงของสิ่งที่ฉันคิดว่าเป็นมาโครที่ดีของกลุ่ม
ตัวอย่างแรกปรากฏในCppUnitซึ่งเป็นกรอบการทดสอบหน่วย เช่นเดียวกับกรอบการทดสอบมาตรฐานอื่น ๆ ที่คุณสร้างคลาสการทดสอบและจากนั้นคุณต้องระบุวิธีการที่ควรจะเรียกใช้เป็นส่วนหนึ่งของการทดสอบ
#include <cppunit/extensions/HelperMacros.h>
class ComplexNumberTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( ComplexNumberTest );
CPPUNIT_TEST( testEquality );
CPPUNIT_TEST( testAddition );
CPPUNIT_TEST_SUITE_END();
private:
Complex *m_10_1, *m_1_1, *m_11_2;
public:
void setUp();
void tearDown();
void testEquality();
void testAddition();
}
อย่างที่คุณเห็นคลาสมีมาโครของบล็อกเป็นองค์ประกอบแรก ถ้าฉันเพิ่มวิธีการใหม่testSubtraction
มันชัดเจนว่าคุณต้องทำอะไรเพื่อให้มันรวมอยู่ในการทดสอบการทำงาน
บล็อกมาโครเหล่านี้ขยายออกเป็นดังนี้:
public:
static CppUnit::Test *suite()
{
CppUnit::TestSuite *suiteOfTests = new CppUnit::TestSuite( "ComplexNumberTest" );
suiteOfTests->addTest( new CppUnit::TestCaller<ComplexNumberTest>(
"testEquality",
&ComplexNumberTest::testEquality ) );
suiteOfTests->addTest( new CppUnit::TestCaller<ComplexNumberTest>(
"testAddition",
&ComplexNumberTest::testAddition ) );
return suiteOfTests;
}
คุณต้องการอ่านและบำรุงรักษาข้อใด
ตัวอย่างอื่นอยู่ในกรอบงาน Microsoft MFC ซึ่งคุณแมปฟังก์ชันกับข้อความ:
BEGIN_MESSAGE_MAP( CMyWnd, CMyParentWndClass )
ON_MESSAGE( WM_MYMESSAGE, OnMyMessage )
ON_COMMAND_RANGE(ID_FILE_MENUITEM1, ID_FILE_MENUITEM3, OnFileMenuItems)
// ... Possibly more entries to handle additional messages
END_MESSAGE_MAP( )
ดังนั้นสิ่งที่แตกต่าง "มาโครที่ดี" จากความชั่วร้ายที่น่ากลัวคืออะไร?
พวกเขาทำงานที่ไม่สามารถทำให้ง่ายขึ้นด้วยวิธีอื่น การเขียนแมโครเพื่อกำหนดค่าสูงสุดระหว่างสององค์ประกอบนั้นไม่ถูกต้องเนื่องจากคุณสามารถทำได้โดยใช้วิธีแม่แบบ แต่มีงานที่ซับซ้อนบางอย่าง (เช่นการแมปรหัสข้อความไปยังฟังก์ชั่นสมาชิก) ซึ่งภาษา C ++ ไม่ได้จัดการอย่างหรูหรา
พวกเขามีการใช้งานที่เข้มงวดและเป็นทางการมาก ในตัวอย่างทั้งสองนี้บล็อกแมโครจะประกาศโดยเริ่มต้นและสิ้นสุดแมโครและแมโครที่อยู่ระหว่างจะปรากฏภายในบล็อกเหล่านี้เท่านั้น คุณมีภาษาซีพลัสพลัสปกติคุณแก้ตัวสั้น ๆ ด้วยมาโครหนึ่งบล็อกจากนั้นคุณจะกลับมาเป็นปกติอีกครั้ง ในตัวอย่าง "มาโครชั่วร้าย" มาโครจะกระจัดกระจายไปทั่วโค้ดและผู้อ่านที่เคราะห์ร้ายไม่มีทางรู้ได้ว่าเมื่อไรที่จะใช้กฎ C ++ และไม่ใช้