使用指向 int 或 short int 的成员创建结构数组?

Posted

技术标签:

【中文标题】使用指向 int 或 short int 的成员创建结构数组?【英文标题】:Creating struct array with member pointing to either int or short int? 【发布时间】:2017-05-31 07:08:25 【问题描述】:

我正在尝试实现一个数据结构,它是一个结构数组。该结构有一个指向unsigned intunsigned short int 的指针。

我的第一次尝试是让结构的数据成员指向一个基类。基类有两个派生类。 g++ 和 clang 都报错 ('Base' 中没有名为 'myArray' 的成员)

在我的第二次尝试中,我使用了 void 指针,但两个编译器再次给出了错误 (错误:指向不完整类型 'void' 的指针的下标)

struct Base  uint32_t *x; ;
struct Derived16 : public Base  uint16_t *myArray; ;
struct Derived32 : public Base  uint32_t *myArray; ;

struct SpecialStruct 
    char *name;
    uint32_t id;
    Base *specialArray;
;

struct SpecialStruct2 
    char *name;
    uint32_t id;
    void *specialArray;
;

int main() 
    // First Attempt
    SpecialStruct myStructs[10];
    myStructs[0].specialArray = new Derived32;
    myStructs[1].specialArray = new Derived16;

    myStructs[0].specialArray->x = new uint32_t[10];
    myStructs[0].specialArray->myArray = new uint32_t[10];
    // ^-- error: no member named 'myArray' in 'Base'

    // Second Attempt
    SpecialStruct2 myStructs2[10];
    myStructs2[0].specialArray = new uint32_t[10];
    myStructs2[1].specialArray = new uint16_t[10];

    myStructs2[1].specialArray[0] = 1;
    // ^-- error: subscript of pointer to incomplete type 'void'

    return 0;

我的问题是:

    有没有可能实现我想象中的数据结构?

    为什么我不能访问派生类数据成员?

【问题讨论】:

如果您想访问 void 指针后面的数据,您必须强制转换该指针(这意味着您必须知道什么它指向的数据类型)。至于“基类”解决方案,您有同样的问题:要从基类访问数组,必须在其中声明它。并且子类不能重新声明一个属性。 【参考方案1】:

“正确”的解决方案是使用模板。但要解决您的问题,void* 可以指向 anything 并且编译器不知道它实际指向什么。您必须将指针转换为正确的类型:

static_cast<Derived32*>(myStructs[0].spcialArray)->x = ...;

【讨论】:

感谢指正,如果您能解释如何使用模板解决此问题,我将非常感谢。【参考方案2】:

类似这样的:

struct BaseStruct
  virtual ~BaseStruct() 
;

template<class T>
struct SpecialStruct: public BaseStruct
  char *name;
  uint32_t id;
  T * spcialArray;
  public:
    virtual ~SpecialStruct()
;


int main() 

    // First Attempt
    vector < BaseStruct*> myStructs;

    SpecialStruct<uint32_t> * myStruct =new SpecialStruct<uint32_t>;
    myStruct->spcialArray = new uint32_t[10];
    myStruct->spcialArray[0] = 1;

    myStructs.push_back(myStruct);
    SpecialStruct<uint32_t>* t = (SpecialStruct<uint32_t>*) myStructs[0];
    cout << t->spcialArray[0];
    return 0;

您也可以使用 unique_ptr 作为向量,并为 Struct 添加虚拟方法

【讨论】:

为什么我们需要重写析构函数? 我的习惯,在这种情况下你不需要它。 我认为基本析构函数“必须”是虚拟的一般规则是正确的。我在 Professional C++,第三版,第 9 章中找到了以下评论 "请注意,析构函数都是虚拟的。根据经验,所有析构函数都应该声明为虚拟的。如果前面的析构函数没有声明为虚拟,代码将继续正常工作。但是,如果曾经对真正指向派生类的基类指针调用delete的代码,破坏链将在错误的位置开始。例如,下面的代码与前面的示例类似,但析构函数不是虚拟的。这变成了当子对象作为指向父对象的指针被访问并被删除时出现问题。"

以上是关于使用指向 int 或 short int 的成员创建结构数组?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Java API 使用 int 而不是 short 或 byte?

const 指向成员的指针是不是默认指向 int?

使用小数据类型(例如 short 而不是 int)会减少内存使用吗?

将指向 int 数组的指针传递给成员函数,错误:数组下标的无效类型“int [int]”

指向 cv 和/或 ref 限定成员函数的指针的 typedef

unsigned short int 和 unsigned int 或 unsigned short 有啥区别?