2012-01-05 24 views
0

あなたは私を助けてくれますか? 私は自分自身を純粋な仮想関数に渡しています。C++自己ミステリーに自己を渡す

nは私のクラスのポインタであるとdataCallbackは独自の(純粋)仮想関数(私は私が下記の説明何が起こるか、なぜ私だけだろう、それは意味をなさない知っている)である
n->dataCallback(handler, n, hangup); 

は今宣言で:今

void MyClass::dataCallback(int handler, void *cbData, bool hangup) { 
    MyClass *This = (MyClass*) cbData; 
.... 
} 

私は、実行時に、この(オブジェクトのポインタ)にこの(上記varaiable)を比較するときは、私が取得:

  1. 値のpoiners(オブジェクトのアドレス)は異なります。
  2. メンバー(私は>メンバー)をチェックするとき、私はそれらの中で異なる値を見つけます。 (これは正しい値ですが、これは未定義の(私にとってはランダムな)値を含んでいますが、呼び出し元側では値が当然正しいので、呼び出し自体の間に魔法のように変化するようです

。間に地球上でこれを可能にどのように?任意のアイデア?

私はこの上で瞑想2時間を費やしてきた、また、結果なしで他のプログラマを尋ねた。

+0

複数の継承を使用していますか? – sth

+2

私の編集内容を確認してください。スタックオーバーフローは[markdown](http://stackoverflow.com/editing-help)を使用しており、インデントコードブロックなどの基本的な部分に少なくとも慣れている必要があります。 – meagar

+0

[this](http://stackoverflow.com/a/372​​5440/140719)または[that](http://stackoverflow.com/a/3108745/140719)は役に立ちますか? – sbi

答えて

2

複数の継承がある場合は、各親クラスへのポインタをキャストしてポインタアドレスを変更することができます。次のことを考えてみましょう:

class A 
{ 
public: 
    int a; 
}; 

class B 
{ 
public: 
    int b; 
}; 

class C : public A, B 
{ 
}; 

クラスCの内部レイアウトは、2つの整数abが含まれています。 C*からA*にポインタをキャストすると、すべて正常です。 B*にキャストする場合は、Bの最初の要素が整数bである必要があるため、ポインタを調整する必要があります。

両方の型がコンパイラに知られているキャストを実行すると、見えない方法で調整が実行されます。それだけで動作します。コンパイラは、適切な調整が何をすべきかを知っています。 void*にキャストすると、このメカニズムが壊れてしまいます。

0

私たちが持っていません処理する完全なテストケースですが、MyClassが多型であり、関連するクラスが存在する場合、キャストはポインタ値を変更できます。void*の使用はそれを破る。

+0

こんにちはLRO、はいクラスは多相であり、複数の継承を使用します。純粋な仮想dataCallbackはそのようなインターフェース(基本クラス)にあります。私はキャストがポインタの値を変更する方法を理解していないと思うが、おそらく私の質問に答えることができる。その間にキャスティングを行う方法についてもう少し分かっていればいいだろう:)一方で、無効なインターフェイスを無効にして、それが修正されているかどうかを確認してください... – user1132655

+0

@ user1132655:Mark'sはとてもうまく説明しました。 –

0

nが、dataCallbackを実装したクラスから派生したクラスへのポインタであり、このクラスが複数の基本クラスを持つ場合に発生します。 1つの(空ではない)基本オブジェクトだけが、完全なオブジェクトと同じアドレスを持つことができます。問題を説明する例を次に示します。

#include <iostream> 

struct Base { 
    int stuff; 
    virtual void f(void * p) { 
     std::cout << (p == this ? "GOOD\n" : "BAD\n"); 
    } 
}; 

struct Other { 
    int stuff; 
    virtual void g() {} 
}; 

struct Derived : Other, Base {}; 

int main() 
{ 
    Derived t; 
    t.f(&t);  // BAD: Passing pointer to Derived to member of Base 
       // (but not guaranteed to print "BAD" - layout is not specified) 

    Base & b = t; 
    b.f(&b);  // GOOD: Passing pointer to Base to member of Base 
} 
+0

こんにちは皆、お返事いただきありがとうございます。すべての答えは正しかった、私はちょうどそれぞれの印をつけることができない:)私はvoid *を適切な明示的な基底クラスに変更したとき、Iveは適切な値を得た。私はまだこの問題を少し複雑に感じている(私はそれを自分自身と推測していないだろう)、しかし病気は私の宿題をする:) – user1132655