我有一个void
指针,我想获得指针所指的内容。
void class :: method(void * pointer)
{
cout<<pointer; // The address which the pointer refers to.
cout<<?; //The content of where the pointer refers to.
}
pointer
的原始类型未知。
编辑:目标是允许创建一个“泛型方法”,它获取任何类型的参数,并为每个参数执行相同的操作。 限制是该方法是虚拟的,因此我不能使用模板方法。
答案 0 :(得分:2)
您需要将void*
强制转换回其原始类型(即在转换为void*
之前)。然后你可以取消引用指针并使用它指向的内容。
EG。 :
void fun(void* ptr) {
int* iptr = (int*) ptr;
std::cout << *iptr;
}
int* iptr = new int(42);
fun(iptr);
以适合您特定用例的方式执行此操作的一种方法是使用类似boost::any
的泛型类型传递对象的类型信息:
#include <iostream>
#include <string>
#include <boost/any.hpp>
class Foo {
public :
virtual void fun(const boost::any& obj) {
if (typeid(int) == obj.type()) {
std::cout << boost::any_cast<int>(obj) << std::endl;
}
else if (typeid(std::string) == obj.type()) {
std::cout << boost::any_cast<std::string>(obj) << std::endl;
}
else {
std::cout << "unsupported type" << std::endl;
}
}
};
int main(void) {
Foo foo;
int i = 42;
std::string s = "str";
float f = 1.1f;
foo.fun(i);
foo.fun(s);
foo.fun(f);
return 0;
}
但这可能会非常冗长,具体取决于您希望支持多少种类型。
答案 1 :(得分:1)
这是不可能的。 C ++中的类型(主要)是编译时属性。在运行时,类型是未知的(它们是erased)。
但是,RTTI存在,特别是对于包含虚拟方法的某些class
的实例。
一般来说,没有可能的伎俩。您可以通过使用某种variant type 来重新设计您的程序,或者通过使用所有您的对象继承的公共根类等等,或者使用union types(最好有自己的受歧视的联盟)。
换句话说:当编译器看到void*
指针时,它甚至不知道该指针所指向的数据的大小。
未来的C ++标准可能会提出一些std::any容器。
也许你可以拥有像
这样廉价的歧视联盟类class Int_or_String {
const bool isint;
union {
int n;
std::string s;
};
Int_or_String(const int i) : isint(true), n(i) {};
Int_or_String(const std::string &st): isint(false), s(st) {};
~Int_or_String() { if (isint) n=0; else
/*not sure*/ s.std::string::~std::string(); };
// much more is missing
};
我甚至不确定显式销毁union成员的语法。
参见例如明确调用析构函数的this question
也许Qt object model可能会激励你。另请参阅其QVariant
通常的方法是在程序中定义一个根类并采用约定,所有对象都继承这个根类(或者甚至所有有意义的数据都在从该根目录派生的对象中)类)。这需要重新设计整个事物。
所以你会决定你的根类是
class Root {
public:
virtual void out(std::ostream&s) =0;
virtual ~Root() =0;
/// other common methods
};
static inline std::ostream& operator << (std::ostream&o, const Root &r)
{ r.out(o); return o; }
class Integer : public Root {
const int num;
public:
Integer(int n) : Root(), num(n) {};
void out (std::ostream &o) { o << num ; };
/// etc...
}; // end class Num
class String : public Root {
const std::string str;
public:
String(const std::string& s) : Root(), str(s) {};
void out (std::ostream &o) { o << str ; };
/// etc...
}; // end class String