Pertanyaan ini memberikan contoh yang jelas tentang bagaimana Anda dapat menggunakan makro dengan buruk. Untuk melihat contoh lain (dan dihibur) lihat pertanyaan ini .
Karena itu, saya akan memberikan contoh dunia nyata dari apa yang saya anggap sebagai penggabungan makro yang baik.
Contoh pertama muncul di CppUnit , yang merupakan kerangka pengujian unit. Seperti halnya kerangka kerja pengujian standar lainnya, Anda membuat kelas pengujian dan kemudian Anda harus menentukan metode apa saja yang harus dijalankan sebagai bagian dari pengujian.
#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();
}
Seperti yang Anda lihat, kelas memiliki blok makro sebagai elemen pertama. Jika saya menambahkan metode baru testSubtraction
, sudah jelas apa yang perlu Anda lakukan untuk memasukkannya dalam uji coba.
Blok makro ini berkembang menjadi seperti ini:
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;
}
Mana yang Anda sukai untuk dibaca dan dipelihara?
Contoh lain adalah dalam kerangka kerja Microsoft MFC, di mana Anda memetakan fungsi untuk pesan:
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( )
Jadi, apa saja hal yang membedakan "Makro Baik" dari jenis jahat yang mengerikan?
Mereka melakukan tugas yang tidak dapat disederhanakan dengan cara lain. Menulis makro untuk menentukan maksimum antara dua elemen adalah salah, karena Anda dapat mencapai hal yang sama menggunakan metode templat. Tetapi ada beberapa tugas kompleks (misalnya, memetakan kode pesan ke fungsi anggota) yang bahasa C ++ tidak ditangani dengan elegan.
Mereka memiliki penggunaan formal yang sangat ketat. Dalam kedua contoh ini blok makro diumumkan dengan memulai dan mengakhiri makro, dan makro antar hanya akan pernah muncul di dalam blok ini. Anda memiliki C ++ normal, Anda permisi sebentar dengan makro, dan kemudian Anda kembali normal lagi. Dalam contoh "makro jahat", makro tersebar di seluruh kode dan pembaca yang malang tidak memiliki cara untuk mengetahui kapan aturan C ++ berlaku dan kapan mereka tidak.