繁体   English   中英

C ++中的Pointer,Class和void *

[英]Pointer, Class and void* in C++

我得到了斐波那契堆的代码。 此代码使用跟随功能比较两个键:

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;
}

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

提前致谢。

更改以下几行

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类型的变量。

您说过您为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;
}

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

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

我在不查看调用代码的情况下就猜测到了-实际上,这不是一个好主意。 如果您也可以发布调用代码,则有助于更好地回答该问题。

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

加上yasouser所说的,您的第一个程序将无法按预期运行。

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

首先关于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或模板函数。

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

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

另一方面,您正在尝试在编写时对类型为T的对象进行值初始化

(T)value;

要么

T(value);

这就是为什么您抱怨类型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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM