将不同类型的指针存储在一个数组中 [英] Store pointers of different type in one array
问题描述
我想在一个数据结构(例如数组,HashMap ...)中存储指向不同类对象的指针.根据此答案,我得出了以下使用无类型的解决方案的信息指针void*
和运算符&*( ClassName* )
用于指针类型重铸:
I want to store pointers to objects of different classes in one data-structure ( such as array, HashMap ... ). According to this answer I came out to following solution using untyped pointer void*
and operator &*( ClassName* )
for pointer type recasting:
#include <stdio.h>
class ClassA{ public: int a; };
class ClassB{ public: double b; };
class Storage{
public:
int n;
void** store;
Storage( int n_ ){ n = n_; store = new void*[n]; };
};
Storage s( 5 );
int main(){
// test store and load ClassA
ClassA a1; a1.a = 16;
s.store[ 0 ] = &a1;
ClassA* a2 = &*( ClassA* ) s.store[ 0 ];
printf( " a2 %i \n", a2->a );
// test store and load ClassB
ClassB b1; b1.b = 15.1455;
s.store[ 1 ] = &b1;
ClassB* b2 = &*( ClassB* ) s.store[ 1 ];
printf( " b2 %f \n", b2->b );
}
现在问题:
- 像
&*( ClassB* )
这样的类型转换有什么不好的地方,除了它不是类型安全的以外? - 此类型转换是否需要任何性能成本?
- 在单个数组中是否有更好(更好,更安全,更快)的方法来存储指向不同类的不同对象的指针?
- Is anything bad about typecasting like
&*( ClassB* )
except that it is not type safe? - Is there any performance cost for this typecasting ?
- Is there any better ( nicer, more safe, faster ) way how store pointer to different objects of different class in a single array?
啊,我发现把它做成void**
实际上是没有用的,因为现在比我现在知道如何稍后识别存储对象的类型了.更好的方法是使用模板和普通的超类.像这样
Ah, I figured out that it is actually not usefull to make it void**
because than I have now way how to recognize type of the stored object later. Better would be do it with template, and common super class. Like this
#include <stdio.h>
#include <cstdlib>
template< class TYPE1 > class Storage{
public:
int n;
TYPE1** store;
Storage( int n_ ){ n = n_; store = new TYPE1*[n]; }; // Constructor
void put( int key, TYPE1* obj ){ store[key] = obj; }; // save data
TYPE1* get( int key ){ return store[key]; }; // load data
};
class Parent { public: int kind; };
class ChildA : public Parent { public: int someData; ChildA( int someData_ ){ kind=0; someData =someData_; } };
class ChildB : public Parent { public: double otherData; ChildB( double otherData_ ){ kind=1; otherData=otherData_; } };
Storage<Parent> mixed( 10 );
int main(){
srand( 15454 );
printf( " ==== initialize by random data and radom type \n" );
for(int i=0; i<mixed.n; i++ ){
if ( (rand()&4) > 0 ){
int someData = rand()&0xFF;
mixed.put( i, new ChildA( someData ) );
printf( " i %i ChildA.someData = %i \n", i , someData );
}else{
double otherData = (rand()&0xFF)/256.0f;
mixed.put( i, new ChildB( otherData ) );
printf( " i %i ChildB.otherData = %f \n", i , otherData );
};
};
printf( " ==== recall stored data \n" );
for(int i=0; i<mixed.n; i++ ){
Parent* obj = mixed.get( i );
if ( obj->kind ==0 ){ printf( " i %i ChildA.someData = %i \n", i , ( (ChildA *) obj )->someData ); }
else { printf( " i %i ChildB.otherData = %f \n", i , ( (ChildB *) obj )->otherData ); };
};
}
推荐答案
像
&*( ClassB* )
这样的类型转换有什么不好的地方,除了它不是类型安全的以外?
Is anything bad about typecasting like
&*( ClassB* )
except that it is not type safe?
将*
后跟&
应用于指针是无操作的,因此只需(ClassB*)
就足够了.同样,您应该使用C ++样式强制转换,在本例中为static_cast<ClassB*>
,而不是C样式强制转换,以使您的意思更加明确.
Applying *
followed by &
to a pointer is a no-op, so simply (ClassB*)
should suffice. Also you should be using C++-style casts, in this case static_cast<ClassB*>
, instead of C-style casts, to make your meaning more explicit.
不好的是,这不仅不是类型安全的,而且还很混乱和滥用C ++语言.
The bad thing is that not only is this not type-safe, but it's also very confusing and an abuse of the C++ language.
此类型转换是否需要任何性能成本?
Is there any performance cost for this typecasting ?
否.
在单个数组中是否有更好(更好,更安全,更快)的方法来存储指向不同类的不同对象的指针?
Is there any better ( nicer, more safe, faster ) way how store pointer to different objects of different class in a single array?
是的,最好的方法是将这些类型的常见行为分解为基类(可能是抽象类),并声明数组以存储指向该基类的指针.如果没有共同的行为,那么将它们全部存储在同一阵列中几乎总是错误的事情.如果出于某些原因您确实想执行此操作,请使用 Boost.任何可能是正确的解决方案.
Yes, the best way is to factor out common behaviour of those types into a base class (possibly abstract), and declare your array to store pointers to that base class. If there is no common behaviour, then storing them all in the same array is almost always the wrong thing to do. If for some reason you really want to do this, something like Boost.Any might be the right solution.
这篇关于将不同类型的指针存储在一个数组中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!