将不同类型的指针存储在一个数组中 [英] Store pointers of different type in one array

查看:161
本文介绍了将不同类型的指针存储在一个数组中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在一个数据结构(例如数组,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 );
}

现在问题:

  1. &*( ClassB* )这样的类型转换有什么不好的地方,除了它不是类型安全的以外?
  2. 此类型转换是否需要任何性能成本?
  3. 在单个数组中是否有更好(更好,更安全,更快)的方法来存储指向不同类的不同对象的指针?
  1. Is anything bad about typecasting like &*( ClassB* ) except that it is not type safe?
  2. Is there any performance cost for this typecasting ?
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆