[英]void pointers in C++
我在一个网站上看到了这个例子,网站提到: - “它的一个用途(void指针)可能是将通用参数传递给一个函数”
// increaser
#include <iostream>
using namespace std;
void increase (void* data, int psize)
{
if ( psize == sizeof(char) )
{ char* pchar; pchar=(char*)data; ++(*pchar); }
else if (psize == sizeof(int) )
{ int* pint; pint=(int*)data; ++(*pint); }
}
int main ()
{
char a = 'x';
int b = 1602;
increase (&a,sizeof(a));
increase (&b,sizeof(b));
cout << a << ", " << b << endl;
return 0;
}
编写如下代码会不会更简单?
void increaseChar (char* charData)
{
++(*charData);
}
void increaseInt (int* intData)
{
++(*intData);
}
int main ()
{
char a = 'x';
int b = 1602;
increaseChar (&a);
increaseInt (&b);
cout << a << ", " << b << endl;
string str;
cin >> str;
return 0;
}
代码更少,而且非常简单。 在第一个代码中,我不得不在这里发送数据类型的大小!
最好使函数类型安全且通用。 最好通过引用而不是指针来获取参数:
template <typename T>
void increment(T& data) {
++data;
}
在C ++中应尽可能避免使用void*
,因为模板和继承提供了类型安全的替代方法。
你的代码绝对是可取的。 void*
失去任何类型安全的假装,你的类型安全过载要好得多。 良好的直觉。
要在C ++中一般支持更多类型,您可以定义类或函数模板,而不是使用void*
。 引用优于指针,但您的代码可以更改为:
template <class T> T increase(T* value)
{
return ++(*value);
}
int main(int argc, char* argv[])
{
int i(0);
increase<int>(&i);
char c(0);
increase<char>(&c);
return 0;
}
作为一个有趣的问题,该网站是什么?
您的解决方案仅适用于int或char。 考虑一下你想要通过一些自定义类型(例如struct)的数组的情况。 在您的代码中,您需要添加一个方法来执行此操作,但是在上面的示例中,不应添加任何行来获取工作示例。
“它的一个用途(void指针)可能是将泛型参数传递给函数”
肯定不是一种好的用途。 将通用参数传递给函数的方法是:
a)允许编写安全代码的模板(以及可能的模板特化),
b) OOP方法。
我喜欢你的第二次increaseInt
和increaseChar
更好的解决方案。 您可以将其重写为:
template<typename T>
void increase(T* pData)
{
++(*pData);
}
它适用于任何支持++
并且安全的类型。
有时你仍然需要一个void指针作为“通用参数” - 例如在使用流行的pthread
库时。 当你产生一个线程时,你可以发送一些任意数据(你想要的任何类型),并且使用 - well - 一个void*
指针完成它。 pthread
库是C而不是C ++,这可能是原因之一,但您可能希望从C ++接口,这确实需要您将void*
指针用作“泛型类型”。 但是,那里没有太大的伤害; 请记住,对于日常编码,有更优雅的解决方案。
其实我觉得这个例子很糟糕。 其中一个规范示例是C库的qsort
,您可以在其中传递void*
以及解释数据的函数。
但是,在C ++中,有更好的机制可用于静默故障。
因此,使用void*
传递通用数据可能应该限于
当你编程C(而不是C ++)时,void *只是你做一些通用的方法。 然而这个例子很可怕。 此方案通常用于回调机制,您可以在其中传递函数指针和void *。 例如:
void handle_crash(void* data)
{
Log* log = (Log*)data;
log->print("We crashed.");
}
Log log;
set_crash_handler(&handle_crash, &log);
您将经常在C框架上看到这一点,例如libxml2或spidermonkey。 在C的情况下,这是唯一可以实现它的东西。 它不是一个非常强大的解决方案。
如果您使用的是C ++,则可以选择更多选项。 基本通用编程可以使用模板或重载完成,如其他答案中所述。 如果您需要可靠的回调机制,您可能需要查看libsigc ++或其他“信号和插槽”框架。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.