0

私は次のコードを持っています:

void testCopy(){
   Balloon* b1=new Balloon(1,5,6,3);
   Balloon* b2=new Ballon(2,4,4,2);
   cpyBallon(b1,b2);
   assert(b1->getCenterx()==5);
   cout<<" cpyBalloon() OK!\n";
}

cpyBalloon() のコードは

void cpyBalloon(TCE& dest,TCE src){
    Balloon* b=(Balloon*) src;
    Balloon* d=new Balloon();
    *d=*b;
    dest=d;
}

ここで、型が void* の場合の TCE。問題は、Balloon* 型のオブジェクト b2 を void*& として渡す方法がわからないことです。次のエラーが発生し続けます。

    ..\src\/Domain/BalloonTest.h:68:18: error: invalid initialization of reference of type 'void*& {aka void*&}' from expression of type 'domain::Balloon*'
    ..\src\/Domain/Balloon.h:102:10: error: in passing argument 1 of 'void domain::delBalloon(void*&)'    

b2 は私が問題を抱えている引数であることは知っていますが、それを機能させるにはどうすればよいかわかりません。

4

2 に答える 2

1

コードが示すように、Balloon クラスがあります。2 つの Balloon インスタンスにメモリを動的に割り当て、それらのコンストラクターを呼び出して、それぞれのデータを入力しました。次に、これらの各オブジェクトのアドレスを適切な生ポインターに格納しました。

この型定義:

typedef void* TCE; // why?

無意味です。void*( )への参照void*&も無意味です。なんで?void*は 1 つの値 (バイト ストリームの最初のバイト) のみを保持するためです ( void*count は型に依存するため、何かを として解釈するとカウントが失われます)。したがって、それはすでにポインターです。バイト ストリーム全体を渡すのではなく、最初のバイトのアドレスだけを渡します。そして、必要に応じて関数でさらに解釈します。

しかし、この場合、そのように解釈する必要はありません。参照は、非常に低いレベルから分析すると、変装したポインターに過ぎず、ポインターの利点を (あまり考えなくても) 安全に享受できます。まだまだありますが、今のところ、これが重要です。

次のいずれかを実行できます。

  1. スタック上に (ローカルに) インスタンスを作成し、それを参照として渡します。
  2. ヒープ上にインスタンスを作成してメモリ アドレスを取得し、それらを渡してさらに処理します。
  3. または...アクション2のコースを取り、それらを としてキャストしてvoid*から、関数でキャストを元に戻すことができます(それが何をするにしても)。

最初に観察します。

    Balloon b1(1,5,6,3);
    Balloon b2(2,4,4,2);

    cpyBalloon(b1, b2);

    void cpyBalloon(Balloon& dest, const Balloon& src) 
    {
        dest = src; // invokes the assignment copy operator (imp. generated)
    }

2 番目の観察:

    Balloon* b1 = new Balloon(1,5,6,3);
    Balloon* b2 = new Balloon(2,4,4,2);

    cpyBalloon(b1, b2);

    void cpyBalloon(Balloon* dest, const Balloon* src) 
    {
        *dest = *src; // invokes the assignment copy operator (imp. generated)
    }

3番目を観察してください(親愛なる主...):

    Balloon* b1 = new Balloon(1,5,6,3);
    Balloon* b2 = new Balloon(2,4,4,2);

    cpyBalloon((void*)b1, (void*)b2);

    void cpyBalloon(void* dest, const Balloon* src) 
    {
        *(Balloon*)dest = *(const Balloon*)src; // oh god...
    }

reinterpet_cast を使用して、型チェックに関するすべてのコンパイラのヘルプを回避することもできますが、これは非常に危険です。これを使用する必要がある場合は、非常に間違っているか、非常に厄介な問題があります (これは、アプローチが非常に間違っていることに起因する可能性があります)。constソースの周りに注意してください。これは、何かをコピーして損傷を受けないようにしたいときはいつでも良い習慣です。

また、これらの状況では多くのメモリ管理が発生することに注意してください。これは単なる単純な状況です。

于 2012-06-05T20:45:19.847 に答える
0

type の左辺値T*( Tis not void) を type の引数として渡すことはできませんvoid *&。これは、言語によって許可されていません。すべてのデータ ポインター型が に変換可能であるからvoid *といって、すべてのデータ ポインター型が に変換可能であるとは限りませんvoid *&。これらはまったく別のものです。

本当にこれを行いたい場合は、 をvoid *&使用して への変換を強制する必要がありますreinterpret_cast。ただし、実行しようとしているように見える操作は、あまり意味がありません。を使用してコードを強制的に「動作」させたとしてreinterpret_castも、それは依然としてハックです。

于 2012-06-05T20:23:04.247 に答える