2012-03-08 11 views
5

質問は件名にあります。実行時にC++クラスまたはObjective-Cクラスのポインターポイントを決定することは可能ですか?

私は安全な削除オブジェクトのいくつかの汎用テンプレート関数を書きたいと思って、このようなものを使用することが可能です:

template< class T > void SafeDelete(T*& pVal) 
{ 
    if(objc_is_cpp_object(pVal)){ 
     delete pVal; 
     pVal = NULL; 
    } 
    else 
     [pVal release] 
} 
+1

なぜ異なる言語で同じ関数名を使用したいのですか?なぜあなたは別の名前を使用してそれらを区別できないのですか? – iammilind

+2

C++の 'delete'とObj-Cの' release'は全く異なることを意味します。両者を融合させることは、最高の疑問を抱くアイデアのように思える。 –

+0

私は最初に別の名前について考えました、そして、私はちょうど両方の言語に対して同じ質問をすることが可能であることについて不思議に思っています。そして、私はそれは非常に良い考えではないかもしれないと思ったが、まだ不思議な気がします:-)これは主に理論的な質問です。 –

答えて

4

コメントに記載されているように、私はC++ deleteとObjective-C releaseを混ぜないことをお勧めします。
ただ、技術的な観点のために、あなたは以下のSFINAEトリックランタイム使用することができます。

template<typename T> struct void_ { typedef void type; }; 

template<typename, typename = void> 
struct CppType { static const bool value = false; }; 
template<typename T> 
struct CppType<T, typename void_<int (T::*)>::type> { static const bool value = true; }; 

template< class T > 
void SafeDelete(T*& pVal) 
{ 
    if(CppType<T>::value || std::is_pod<T>::value) { // <----- 
    delete pVal; 
    pVal = 0; 
    } 
    else { 
    // [pVal release]; 
    } 
} 

おそらく、is_podはC++ 11で利用可能ですが、などを後押ししかし、それは実装が簡単です。

+0

"typename void_ :: type"を意味するものを説明できますか?これまでのところ、objcオブジェクトの場合のこの文字列はvoid型に置き換えられ、特殊化されたテンプレートのバージョンはfalseを返すということを理解しています。しかし、これがどうして起こるかを理解することはできません。ありがとうございました。 –

+0

@ andrey.sでは、このメカニズムはSFINAEと呼ばれています。 'int(T :: *)'はメンバ変数へのポインタを意味します。今、メンバーへのポインタは、C++の 'class'や' union'のみ可能で、他のエンティティは使用できません。したがって、ある型がC++の 'class'型の場合、' CppType :: value'は 'true'になり、C++固有のタスクを実行することができます。 – iammilind

+2

それは本当にクール、ありがとう! –

2

Objective-CのポインタはC++のポインタと同じである:4〜8メモリ内のさまざまなオブジェクトを指すワード整数値。 Objective-Cコンパイラは、C、C++、Objective-Cオブジェクトのレイアウトなど、複数の形式で値を出力することをサポートしています。

これだけです。実際にはそれ以上のことはありません。あなたはそのようにそれをテストすることができ、その後

template <class T> 
class Magic { 
    private: 
     const char magic[] = 1234567; 
    public: 
     bool is_object() const { 
      return magic == 1234567; 
     } 
} 

bool is_cpp(void *ptr) { 
    return ((Magic*) ptr)->is_object(); 
} 

をしかしことをあらかじめご了承

あなたのようなフィールドは常に魔法の値を含むクラスを作成ハック何かをしようとすることができますこれは極端にハッキーです。

+0

あなたの提案は、すべてのcppオブジェクトにベースの "Magic"クラスを使用していますか? –

+0

これは一般的な考えです。これは特別な値がないので、プロダクションでやりたいことではありません... – Alex

+0

Objective-Cにはこの魔法が付いています:すべてのobjective-cポインタアドレスは 'struct objc_object'型です。その(albiet private)定義慣用的に 'isa_t isa'メンバを含んでいなければなりません...私は実行時検査については気にしませんが、私は個人的に' objc_object :: isa'をSFINAEのために十分に見つけました。 'objc :: traits :: is_object '; http://git.io/vCsLa - 詳細はhttp://unixjunkie.blogspot.de/2006/02/nil-and-nil.htmlとobjcランタイムソース - http://www.opensourceを参照してください。 apple.com/source/objc4/objc4-647/runtime/objc-private.h – fish2000

関連する問題