[英]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.