「空」は単に「何もない」という意味です。「void*」ポインターは、特に何も指していません。これは、「このポインターが何を指しているのかわかりません」という言い方です。void* ポインターは、あらゆる種類のポインターを受け取ることができるすべてをキャッチしますが、void* ポインターから他の種類に移動する場合は、明示的にキャストする必要があります。
あなたの最初の問題について:
「1234 Pointer Street」に住んでいた場合、「1234」という数字に魔法のようなものは何もなく、ただの数字です。それを「ポインター」、つまり家の番号として扱った場合にのみ、それはあなたに何かを伝えます。特定の通りにある家を「指し示し」ます。
コンピュータの場合、その通りはメモリです。
int a = 0;
int* b = 0;
変数 "a" と "b" の両方に数値 "0" が含まれています。
b = b + 1;
見る?完全に有効です。そう
void foo(int a, int* b)
{
a = a + 1;
b = b + 1;
}
void bar()
{
int x = 0;
int* y = 0;
foo(x, y);
// 'x' and 'y' are still zero here, they have to be, or you couldn't do
foo(0, 0);
}
通常の変数とは異なるいくつかの特徴を持つポインター。
int a = 0;
int* b = 0;
a = a + 1; // now a = 1
b = b + 1; // now b = b + sizeof(int) => 4.
ポインターが最も得意とすることは、C/C++ の「逆参照」演算子に値を提供することです。
a = *(b);
通りの例に戻ると、「1234 Pointer Street」の住所を b に割り当てると、次のようになります。
b = 1234;
そこに何かを届けたいとしたら?
*b
これは次のことを意味します。 b が記述するアドレスの内容。
定義に戻りましょう
int* b;
これは、「bは整数のアドレスです」と言っています。特定の整数のアドレスを取得するにはどうすればよいですか?
// imagine a set of mailboxes.
int box1, box2, box3, box4, box5;
// lets put something interesting into box 3.
box3 = 5;
// now let's address somethign to box3.
// "&" is the "address of" operator.
int* pointer = &box3;
// now lets put something more interesting in pointer.
pointer = 10;
// whoops - that was wrong, we just changed the ADDRESS to some random numeric value.
// what we mean't was:
*pointer = 10;
printf("box 3 contains %d\n", box3);
// answer? 10, not 5.
"pointer = &box3" を設定した後、"pointer" に box3 のメモリ内のストレージの場所を設定したので、"*pointer = 10" を使用してそのアドレスに書き込むと、box3 のストレージ アドレスに書き込みました。
あなたは void *p1; について尋ねました。ボイド *p2; &p1 = &p2; p1 = p2; *p1 = *p2;
「&p1 = &p2」は、「p1 のアドレスは p2 のアドレスです」と言い、正当ではなく、コンパイルされません。
「p1 = p2」は正当ですが、「p2 と同じアドレスを p1 に割り当てる」と書かれています。
"*p1 = *p2" は無効です。これは、void を指す void ポインターを使用しているためです。さらに、p1 と p2 を互いに等しくしたばかりなので、null 操作になります。
最初の問題を解決するには、呼び出し元が作成している新しい値を受け取る方法を提供する必要があります。
オプション 1: ポインターツーポインターを受け入れる
これは非常に昔ながらの C の方法ですが、これまでのコードはあまり C++ に見えないので、最初にリストします。
void ItemGen(void** Holder)
{
Item* NewItem = new Item;
NewItem->Init(); // why doesn't the constructor do this?
// ** means pointer to storage that is itself also a pointer,
// so if we dereference it once we will be refering to the inner pointer.
*Holder = NewItem;
}
オプション 2: ポインターを返す
void* ItemGen() // Why isn't this "Item*"?
{
Item* NewItem = new Item;
NewItem->Init();
return NewItem;
}
オプション 3: リファレンスを取る
void ItemGen(Item*& Holder)
{
Holder = new Item;
Holder->Init();
}
これは、「ホルダーはアイテム型のストレージへのポインターへの参照です」と言っています。渡された値の一時的なローカル コピーを作成する代わりに、渡された値のエイリアスであることを除いて、"Item*" ポインターとまったく同じです。
ポインターの型情報を絶対に破棄する必要がある場合:
void ItemGen(void*& Holder)
{
Item* NewItem = new Item;
NewItem->Init();
Holder = NewItem;
}
これまでのところ C++ を使用しているように見えるレベルでは、void* ポインターの使用はおそらく間違っていると思います。