1

私の関数では、両方のポインターが同じタイプのオブジェクトを指している場合IsSameに戻りたいと思います。したがって、中間呼び出しのみが返されます。同じと見なされるべきではありません。truetrueD1B

以下はまさに私が欲しいもののようですが、標準によれば安全ですか?

#include <stdio.h>

class B { virtual void foo() {} };
class D1 : public B { };
class D2 : public B { };
class D3 : public B { };

bool IsSame(B*a, B*b) {
    if (a == 0 || b == 0)
        return false;
    return *(intptr_t*)a == *(intptr_t*)b;
}

int main() {
    D1 d1;
    D2 d2;
    D1 d1b;
    B b;
    printf("%d %d %d\n", IsSame(&d1, &d2), IsSame(&d1, &d1b), IsSame(&d1, &b));
}

出力:

0 1 0
4

2 に答える 2

6

2 つのオブジェクトに同じ v-table があるかどうかを確認しようとしています。C++ 標準は、オブジェクトのレイアウト内のどこにあるかは言うまでもなく、v-table ポインターの存在についても言及していません。したがって、あなたのソリューションは自明であり、プログラムの動作は実際には未定義です。

2 つの基本ポインターが同じ派生型を持ち、RTTI がないかどうかを確認したい場合は、派生型の ID を知らせる何らかのメカニズムが必要になります。これはおそらく、すべての派生型が実装する必要がある ID を返す仮想メソッドを意味します。

于 2013-04-25T00:41:20.480 に答える
4

以下はうまくいくようです:

#include<typeinfo>
#include<iostream>

class B { virtual void foo() {} };
class D1 : public B { };
class D2 : public B { };
class D3 : public B { };


template<typename T1, typename T2>
bool is_same(const T1& t1, const T2& t2) {
  return typeid(t1) == typeid(t2);
}

bool is_same_no_template(const B& b1, const B& b2) {
  return typeid(b1) == typeid(b2);
}

int main(){
    D1 d1;
    D2 d2;
    D1 d1b;
    B b;
    std::cout<<std::boolalpha
             <<"d1 == d2  ? "<<is_same(d1, d2)<<std::endl
             <<"d1 == d1b ? "<<is_same(d1, d1b)<<std::endl
             <<"d1 == b   ? "<<is_same(d1, b)<<std::endl;

    std::cout<<"No Template"<<std::endl;

    std::cout<<std::boolalpha
             <<"d1 == d2  ? "<<is_same_no_template(d1, d2)<<std::endl
             <<"d1 == d1b ? "<<is_same_no_template(d1, d1b)<<std::endl
             <<"d1 == b   ? "<<is_same_no_template(d1, b)<<std::endl;

    return 0;
}

gcc 4.7.2 でコンパイルすると、次の出力が得られます。

[Prompt] g++ example.cpp -std=c++11
[Prompt] ./a.out
d1 == d2  ? false
d1 == d1b ? true
d1 == b   ? false
No Template
d1 == d2  ? false
d1 == d1b ? true
d1 == b   ? false

「ランタイム型情報」(RTTI; -fno-rttigcc のコンパイル フラグ) なしでコンパイルすることにした場合、このコードはコンパイルされないことに注意してください。

于 2013-04-25T00:16:18.327 に答える