2016-10-15 5 views
0

次のコードは、コンストラクタでキャストが行われているにもかかわらず、voidポインタを参照できないため、コンパイルされません。このコードをコンパイルするか、型の安全性を無効にするにはどうしてですか?コンストラクタでvoid *をキャストして値にアクセスする

#include "stdafx.h" 
#include <iostream> 

using namespace std; 

IntWrapper(int _value) : value{ nullptr } 
{ 
    value = new int(_value); 
    value = static_cast<int*>(value); 
} 

int main() 
{ 
    IntWrapper* foo = new IntWrapper(10); 
    cout << *foo->value; 
    cin.get(); 
    return 0; 
} 

私はこのコードは、コンソールアプリケーションである一方で、それは非現実的なエンジンで書かれているコードのテストとして意図されていることに注意すべきです。このため、クラステンプレートを使用して必要な機能を実現することはできません。

+1

なぜボイドポインタを使用しているのですか? –

+0

固定数の型(int、float、doubleなど)にすることができ、テンプレートを使用できないクラスが必要です。これは、Unrealでこれをテストするのが苦痛なので、クラスの簡略版です。私はラッパーの中に複数の型を定義することでこれを実現できると思っています。 – InvertedIdeals

+1

おそらく '組合 'ですか? –

答えて

2

new intは、int*を返します。 int*からint*へのキャスティングは、何もしておらず、何もしません。 newの結果をそれ自体にキャストした後は、void*変数に格納します。この変数は暗黙的にvoid*にキャストされます。

あなたがfoo->valueにアクセスするとそれはあなたがvalueのために定義されたタイプだから、タイプがvoid*です。コンストラクタで何をしても、それは変わりません。 voidポインタをキャストしたい場合は、ここで行います。つまり、foo->valueint*にキャストして逆参照することができます。

もちろん、valueを最初にint*にするほうがはるかに簡単です。

+0

最初に 'void *'を使用しないでください:) – Rakete1111

+0

これを受け入れるという点では、状況に適した実装であるという信念を跳ね返す必要があります。仮に、型チェックを無効にしてコンパイラを強制的に実行する方法はありますか?私はもちろん、その機能を別々に実装することができますので、void *はありませんが、これが課された状況下で可能かどうかを知ることはできません。 – InvertedIdeals

+0

@InvertedIdeals何を続行しますか?演算子<<のintオーバーロードを呼び出して続行しますか?これは、 'foo-> value'が' int'を指していることをコンパイラーに伝えなければ、不可能です。 'foo-> value'が' void * 'として宣言されているとき、コンパイラがそれを理解する方法はありません。 – sepp2k

0

最初に " - >"を使用すると、その左側の用語を間接参照しています。

あなたのケースでは* fooですが、fooはIntWrapper *であるため、* fooはIntWrapperです。

構文はfoo-> valueまたは(* foo).valueです。

また、他の答えで言われていることはすべて真ですが、この静的なキャストは絶対に何もしません。

ので、正しいコードがもっとこのようになります:

#include "stdafx.h" 
#include <iostream> 

using namespace std; 

struct IntWrapper 
{ 
    IntWrapper(int _value) : value{ new int(_value) } {} 
    void * value; 
}; 

int main() 
{ 
    IntWrapper * foo = new IntWrapper(10); 
    cout << *((int *)(foo->value)); 
    cin.get(); 
    return 0; 
} 

あなたはint型のラッパーを作っているので、構造体の内部のvoid *型は非常に有用ではありません。それをint *にするとエラー処理が改善され、foo-> valueを出力したり、intとしてアクセスしたりする必要はありません。

+0

実際の質問を「IntWrapper」と呼ぶことによって、おそらくそれが不明瞭になりました。もちろん、foo-> valueを実行することでメモリアドレスを返すことができますが、* foo-> valueを実行してラッパー構造体の内部でキャストを実行できるようにしたいと考えています。この実装を行う必要性よりもむしろ好奇心です。 – InvertedIdeals

+0

あなたの値がvoid *の場合は、これを行うことはできません。これは不完全な型であるため、参照を解除することはできません。間接参照するには完全な型を使用する必要があります。 –

関連する問題