C++ 中的指针、类和 void*

发布于 2024-11-08 18:10:27 字数 1187 浏览 0 评论 0原文

我得到了斐波那契堆的代码。此代码使用以下函数来比较两个键:

int
cmp(void *x, void *y)
{
    int a, b;
    a = (int)x;
    b = (int)y;

    if (a < b)
        return -1;
if (a == b)
        return 0;
    return 1;
}

之所以有效,是因为 KEY 当前是 INT 数字。

我想修改此代码以使用我的名为“Node”的类。这个类已经实现了运算符<。 >、<=、== 和 >=。

我在代码中的适应是:

Node a, b   // instead int a, b
a = (Node)x;
b = (Node)y;

但我得到了错误:

dijkstra.cpp:168: error: no matching function for call to 'Node::Node(void*&)'
graph.h:39: note: candidates are: Node::Node()
graph.h:39: note:                 Node::Node(const Node&)

我也尝试了:

Node a, b   // instead int a, b
a = (Node*)x;
b = (Node*)y;

并得到了错误:

dijkstra.cpp:168: error: no match for 'operator=' in 'a = (Node*)x'
graph.h:39: note: candidates are: Node& Node::operator=(const Node&)

我放弃尝试设置值并解决问题如下:

int cmp(void *x, void *y)
{ 
    if ((Node*)x < (Node*)y)
        return -1;
    if ((Node*)x == (Node*)x)
        return 0;
    return 1;
}

我想了解我在中做错了什么前面的例子。

提前致谢。

I get a code for Fibonacci Heap. This code uses the follow function to compare two keys:

int
cmp(void *x, void *y)
{
    int a, b;
    a = (int)x;
    b = (int)y;

    if (a < b)
        return -1;
if (a == b)
        return 0;
    return 1;
}

This works because the KEY is currently a INT number.

I would like to adapt this code to use my class called "Node". This class have implemented the operator <. >, <=, == and >=.

My adaptation in the code was:

Node a, b   // instead int a, b
a = (Node)x;
b = (Node)y;

But I get the error:

dijkstra.cpp:168: error: no matching function for call to 'Node::Node(void*&)'
graph.h:39: note: candidates are: Node::Node()
graph.h:39: note:                 Node::Node(const Node&)

I tried also:

Node a, b   // instead int a, b
a = (Node*)x;
b = (Node*)y;

and get the error:

dijkstra.cpp:168: error: no match for 'operator=' in 'a = (Node*)x'
graph.h:39: note: candidates are: Node& Node::operator=(const Node&)

I give up to try set the value and solve the question as a follow:

int cmp(void *x, void *y)
{ 
    if ((Node*)x < (Node*)y)
        return -1;
    if ((Node*)x == (Node*)x)
        return 0;
    return 1;
}

I would like to understand what I am doing wrong in the previous examples.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

草莓味的萝莉 2024-11-15 18:10:27

将以下行更改

a = (Node*)x;
b = (Node*)y;

a = *( (Node*) x); 
// type cast from void* to Node* and then fetch the contents by dereferencing the pointer.

b = *( (Node*) y);

您只是将指针从 void* 类型转换为 Node* 并尝试将指针分配给类型为 Node 的变量>。

Change the following lines

a = (Node*)x;
b = (Node*)y;

to

a = *( (Node*) x); 
// type cast from void* to Node* and then fetch the contents by dereferencing the pointer.

b = *( (Node*) y);

You were merely type casting the pointers from void* to Node* and trying to assign the pointer to a variable of type Node.

最舍不得你 2024-11-15 18:10:27

您说您为 Node 类重载了运算符(<、== 等)。但该函数按原样比较指针。您需要取消引用它们才能使用运算符。试试这个:

int
cmp(void *x, void *y)
{
    Node *a, *b;
    a = (Node*)x;
    b = (Node*)y;

    if (*a < *b)
        return -1;
    if (*a == *b)
        return 0;
    return 1;
}

You said you overloaded operators(<,==,etc..) for the Node class. But the function compares pointers as is. You need to dereference them in order to use your operators. Try this:

int
cmp(void *x, void *y)
{
    Node *a, *b;
    a = (Node*)x;
    b = (Node*)y;

    if (*a < *b)
        return -1;
    if (*a == *b)
        return 0;
    return 1;
}
天荒地未老 2024-11-15 18:10:27

看起来您正在使用对 Node 对象的引用来调用 cmp 函数(或者通过回调调用它)。如果是这种情况,您可以将代码更改为

Node& a = static_cast<Node&>(*x);
Node& b = static_cast<Node&>(*y);

“我猜”,而无需查看调用代码 - 老实说,这不是一个好主意。如果您也能贴出调用代码,将有助于更好地回答问题。

Looks like you are calling the cmp function (or it is getting called via a callback) with a reference to the Node object. If that is the case you can change your code to

Node& a = static_cast<Node&>(*x);
Node& b = static_cast<Node&>(*y);

I am guessing this without looking at the calling code - which, honestly is not a good idea. If you can post the calling code too, it will be helpful to answer the question better.

哭了丶谁疼 2024-11-15 18:10:27

没有理由比较 (Node*) 或 (void*) 值 - 这只是指针,您将比较内存地址。看起来让第一个示例工作所需的只是实现 operator =

There no reason to compare (Node*) or (void*) values - this is just pointers and you will compare memory addresses. It looks like all you need to make first example work is implement operator =.

雨夜星沙 2024-11-15 18:10:27

添加 yasouser 所说的内容,您的第一个程序将无法按预期工作。

a = *(int*)x;
b = *(int*)y;

Adding to what yasouser said, your first program will not work as expected.

a = *(int*)x;
b = *(int*)y;
夏夜暖风 2024-11-15 18:10:27

首先关于您的 cmp 函数本身:
通常人们只实现operator<;当实现operator>时,通常是通过使用相反的参数调用已经实现的operator<。您的 cmp 实现还需要 Node 实现 operator==,这可能是不必要的。

另外,如果您的函数接受 void* 但在内部将它们转换为 NODE* 并取消引用它们,并且它仍然以通用“cmp”命名,则会出现一个小问题。

更好的实现是这样的:

int NodeCmp(void *x, void *y)
{ 
// handle NULL pointers here
    if (*(Node*)x < *(Node*)y)
        return -1;
    if (*(Node*)y < *(Node*)x)
        return 1;
    return 0;
}

如果您愿意,您可能需要研究 std::less 或模板函数。

First about your cmp function itself:
usually people only implement operator<; when operator> is implemented, it is usually through a call to the already implemented operator< with reversed parameters. Your implementation of cmp also requires the Node implement operator==, which might be unnecessary.

Also, there is a small issue if your function accepts void* but internally converts them to NODE* and dereferences them AND it yet it is named with a generic "cmp".

A better implementation would be this:

int NodeCmp(void *x, void *y)
{ 
// handle NULL pointers here
    if (*(Node*)x < *(Node*)y)
        return -1;
    if (*(Node*)y < *(Node*)x)
        return 1;
    return 0;
}

If you're feeling up to it, you might want to look into std::less or template functions.

ペ泪落弦音 2024-11-15 18:10:27

通常,当您将 void* 传递给函数时,您必须将该指针强制转换为所需类型的另一个指针。例如:

void func(void* a, void* b)
{
    int* c, d;
    c = (int*)a;
    d = (int*)b;
    //... continue rest of function
}

另一方面,您在编写

(T)value;

或时

T(value);

尝试对 T 类型的对象进行值初始化这就是为什么您会收到关于 T。

您应该做的是转换为 T* 类型的指针,然后取消引用这些新的转换指针,以在实际对象之间进行任何您想要的比较 类型为 T。例如(假设 T 是您想要比较的某种所需类型......即,这不是模板):

int cmp(void* a, void* b)
{
    T* c, d;
    c = (T*)a;
    d = (T*)b;

    if (*c < *d)
        return -1;
    else if (*c > *d)
        return 1;
    else
        return 0;
}

Typically when you are passing a void* to a function, you must then cast the pointer to another pointer of the type you are wanting. For example:

void func(void* a, void* b)
{
    int* c, d;
    c = (int*)a;
    d = (int*)b;
    //... continue rest of function
}

You on the otherhand are trying to value initialize an object of type T when you write

(T)value;

or

T(value);

That is why you're getting complaints about not having a proper constructor type for the object of type T.

What you should be doing is casting to a pointer of type T*, and then dereferencing those new casted pointers to-do whatever comparisons you want between the actual objects of type T. For example (assume T is some desired type you want to compare ... i.e., this is not a template):

int cmp(void* a, void* b)
{
    T* c, d;
    c = (T*)a;
    d = (T*)b;

    if (*c < *d)
        return -1;
    else if (*c > *d)
        return 1;
    else
        return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文