-3

所以现在我正在尝试为我正在制作的一个小游戏做一些漂亮的代码,我遇到了一些关于指针的事情一直困扰我一段时间。

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

void ItemGen(void* Holder){

    Item* NewItem
    NewItem = new Item*
    NewItem->Init();
    Holder = NewItem;

}

它实际上不是在制作“物品”,而是从物品继承的各种物品,这只是我让它变得更简单。

持有人被改变但从未在函数之外进行,我应该如何改变它,这样它就可以了。

最重要的是,我对可能发生的某些事情感到困惑,我只想知道当你这样做时会发生什么。或者真的是他们之间的区别

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

哦,有没有办法对指针进行异或运算,这样我就可以在没有持有指针的情况下交换它们。

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

4

3 回答 3

0

“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* 指针的使用可能是错误的。

于 2013-06-21T02:24:21.277 回答
0

我正在回答这一点“持有人已更改,但从未在函数之外进行,我应该如何更改它,以便它可以。”

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()
  }

}

于 2013-06-21T02:11:53.883 回答
0

指针和其他变量一样是变量,因此按值传递给函数。您只是为指针的参数副本分配了一个新值。

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

void ItemGen(void *& Holder);

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

于 2013-06-21T01:44:22.373 回答