2009年9月16日 星期三

C++ 與 instanceof

C++ 本身是沒有提供 instanceof 關鍵字,不過我們可以利用簡單地實作出該語意:

template <class Class, typename T>
inline bool
instanceof(T const &object)
{
    return dynamic_cast<class const *>(&object);
}

不過我發現如果要用 dynamic_cast,我們的 class 至少要有一個 virtual function,因為 C++ 的 RTTI 實作是依賴 vtable 的。

以下是整個範例程式:

#include <iostream>
#include <cstdlib>

using namespace std;



template <class Class, typename T>
inline bool
instanceof(T const &object)
{
    return dynamic_cast<Class const *>(&object);
}



class A
{
public:
    virtual ~A() {}
};

class B : public A { };
class C : public A { };
class D : public B, public C { };

class E
{
public:
    virtual ~E() {}
};



int
main()
{
    A a;
    B b;
    C c;
    D d;
    E e;

    A& aa = a;
    A& ab = b;
    A& ac = c;
    A& ad = *static_cast<B *>(&d);

#define CHECK(CLASS, REF) \
    do \
    { \
        if (instanceof<CLASS>(REF)) \
        { \
            cout << #REF " is an instance of " #CLASS << endl; \
        } \
        else \
        { \
            cout << #REF " is NOT an instance of " #CLASS << endl; \
        } \
    } \
    while (0);

    CHECK(A, aa);
    CHECK(A, ab);
    CHECK(A, ac);
    CHECK(A, ad);
    CHECK(A, e);

    CHECK(B, aa);
    CHECK(B, ab);
    CHECK(B, ac);
    CHECK(B, ad);
    CHECK(B, e);

    CHECK(C, aa);
    CHECK(C, ab);
    CHECK(C, ac);
    CHECK(C, ad);
    CHECK(C, e);

    CHECK(D, aa);
    CHECK(D, ab);
    CHECK(D, ac);
    CHECK(D, ad);
    CHECK(D, e);


    return EXIT_SUCCESS;
}

沒有留言:

張貼留言