This question already has an answer here:
这个问题已经有了答案:
- Are array of pointers to different types possible in c++? 7 answers
- 在c++中,指向不同类型的指针数组可能吗?7的答案
I'm trying to create an object that can be of any type. Here's the code:
我在尝试创建一个可以是任何类型的对象。这是代码:
#include <stdio.h>
class thing
{
public:
void *p;
char type;
thing(const char* x)
{
p=(char*)x;
type=0;
}
thing(int x)
{
p=(int*)x;
type=1;
}
thing(bool x)
{
p=(bool*)x;
type=2;
}
/*
thing(float x)
{
p=(float*)x;
type=3;
}
*/
void print()
{
switch(type)
{
case 0:
printf("%s\n", p);
break;
case 1:
printf("%i\n", p);
break;
case 2:
if(p>0)
printf("true\n");
else
printf("false\n");
break;
case 3:
printf("%f\n", p);
break;
default:
break;
}
}
};
int main()
{
thing t0("Hello!");
thing t1(123);
thing t2(false);
t0.print();
t1.print();
t2.print();
return 0;
}
Code is working and when I run the program, it displays:
代码正在工作,当我运行程序时,它显示:
Hello!
123
false
But if I uncomment the float constructor, the compiler writes the following error:
但是如果我取消对float构造函数的注释,编译器会写入以下错误:
main.cpp: In constructor 'thing :: thing (float)': main.cpp: 30:13:
error: invalid cast from type 'float' to type 'float *'
Why is it not working for float type? I use: Windows XP SP3, MinGW GCC 4.7.2.
为什么它不适合浮动类型?我使用:Windows XP SP3, MinGW GCC 4.7.2。
1 个解决方案
#1
2
You should not be casting from random types to pointer types. Even though casting char const *
, int
, and bool
appear to work for you, they are not any more what you want than casting float to a pointer. In fact you should view any cast in C++ as a warning sign that you may be doing something incorrectly.
不应该将随机类型转换为指针类型。即使对char const *、int和bool进行强制转换似乎对您有用,但它们并不比对指针进行强制转换更合适。实际上,您应该将c++中的任何类型转换视为一个警告信号,表明您可能正在做一些不正确的事情。
Instead you should do something like the following.
相反,你应该做如下的事情。
class thing {
private:
union {
char const *cs;
int i;
bool b;
float f;
};
enum class type { cs, i, b, f } stored_type;
public:
thing(const char* x) : cs(x), stored_type(type::cs) {}
thing(int x) : i(x), stored_type(type:: i) {}
thing(bool x) : b(x), stored_type(type:: b) {}
thing(float x) : f(x), stored_type(type:: f) {}
void print()
{
switch(stored_type)
{
case type::cs:
std::printf("%s\n", cs); break;
case type::i:
std::printf("%i\n", i); break;
case type::b:
std::printf("%s\n", b ? "true" : "false"); break;
case type::f:
std::printf("%f\n", f); break;
}
}
};
Or better yet you could use a library that already does this for you, such as boost::variant, or boost::any.
或者更好的是,您可以使用一个已经为您完成此任务的库,例如boost::variant,或者boost: any。
#1
2
You should not be casting from random types to pointer types. Even though casting char const *
, int
, and bool
appear to work for you, they are not any more what you want than casting float to a pointer. In fact you should view any cast in C++ as a warning sign that you may be doing something incorrectly.
不应该将随机类型转换为指针类型。即使对char const *、int和bool进行强制转换似乎对您有用,但它们并不比对指针进行强制转换更合适。实际上,您应该将c++中的任何类型转换视为一个警告信号,表明您可能正在做一些不正确的事情。
Instead you should do something like the following.
相反,你应该做如下的事情。
class thing {
private:
union {
char const *cs;
int i;
bool b;
float f;
};
enum class type { cs, i, b, f } stored_type;
public:
thing(const char* x) : cs(x), stored_type(type::cs) {}
thing(int x) : i(x), stored_type(type:: i) {}
thing(bool x) : b(x), stored_type(type:: b) {}
thing(float x) : f(x), stored_type(type:: f) {}
void print()
{
switch(stored_type)
{
case type::cs:
std::printf("%s\n", cs); break;
case type::i:
std::printf("%i\n", i); break;
case type::b:
std::printf("%s\n", b ? "true" : "false"); break;
case type::f:
std::printf("%f\n", f); break;
}
}
};
Or better yet you could use a library that already does this for you, such as boost::variant, or boost::any.
或者更好的是,您可以使用一个已经为您完成此任务的库,例如boost::variant,或者boost: any。