指针(void指针)和函数有一点混淆



所以现在我正试图为我正在制作的小游戏做一些nift代码,我遇到了一些一直困扰我一段时间的指针。

但首先,我试图让一个函数接受一个void*并给那个void*一个值,但它似乎并没有像我习惯的那样实际停留在函数之外。所以…

void ItemGen(void* Holder){
    Item* NewItem
    NewItem = new Item*
    NewItem->Init();
    Holder = NewItem;
}

它实际上并不是创建"项",而是从一个项继承的各种项,这只是我简化它。

Holder被改变了,但从来没有在函数之外,我应该如何改变它,使它在函数之外。

最重要的是,我对可能发生的某个事件有点困惑,我只是想知道当你做这些时会发生什么。或者它们之间的区别

void *p1;
void *p2;
&p1 = &p2;
p1 = p2;
*p1 = *p2;

哦,有没有一种方法可以对指针进行异或操作,这样我就可以用一个保持指针来交换它们。

我觉得我问了非常愚蠢的问题,但令人困惑的仅仅是因为他们是空*。

指针和其他变量一样,是通过值传递给函数的。你只是给指针的形参副本赋了一个新值。

如果要更改传递给函数的变量,必须通过引用或指针传递。最好是前者。

void ItemGen(void *& Holder);

顺便说一下,这是一个可怕的命名约定。

我回答这一点"持有人得到改变,但从来没有使它在函数之外,我应该如何改变这一点,这样做。"

void ItemGen(Item** Holder){
 Item* NewItem
 NewItem = new Item*
 NewItem->Init();
 *Holder = NewItem;
}
void someotherfunc() {
 Holder * holder=0;
 ItemGen(&holder)
 if(holder!=0) {
      holder->dosomething()
  }

}

"void"就是"没有"的意思。"void*"指针不指向任何特定的对象。这是在说"我不知道这个指针指向什么";void*指针是一个catch all,可以接收任何类型的指针,但是如果你想从void*指针转换到任何其他类型,你必须显式地强制转换它。

关于你的第一个问题:

如果你住在"指针街1234号","1234"这个数字没有什么神奇之处,它只是一个数字。只有当你把它当作一个"指针"——一个门牌号时,它才会告诉你任何事情。它"指向"某条街上的一所房子。

对于计算机来说,整条街就是存储器。

int a = 0;
int* b = 0;

变量"a"one_answers"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"地址,它将是:

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 %dn", box3);
// answer? 10, not 5.

在设置了"pointer = &box3"之后,我们将"pointer"填充为box3在内存中的存储地址,因此当我们使用"*pointer = 10"写入该地址时,我们写入的是box3的存储地址。

你问void * p1;void * 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*指针的使用可能是错误的。