“void”只是意味着“没有”。“void*”指针特别指向任何内容。这是一种说“我不知道这个指针指向什么样的东西”的方式;一个 void* 指针是一个可以接收任何类型指针的 catch all,但是如果你想从一个 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);
回到街道的例子,如果我们为 b 分配“1234 Pointer Street”地址,它将是:
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”后,我们用box3在内存中的存储位置填充“pointer”,所以当我们使用“*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 彼此相等,因此这将是一个空操作。
要解决您最初的问题,您需要为调用者提供一种方法来接收您正在创建的新值。
选项 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();
}
这表示“Holder 是对指向 Item 类型存储的指针的引用”。它与“Item*”指针完全一样,除了创建传入值的临时本地副本之外,它是传入值的别名。
如果您绝对必须丢弃指针的类型信息:
void ItemGen(void*& Holder)
{
Item* NewItem = new Item;
NewItem->Init();
Holder = NewItem;
}
到目前为止,在您似乎使用 C++ 的级别上,我猜您对 void* 指针的使用可能是错误的。