我有一段时间没有和c一起工作过,但我刚刚用它开始了一个项目.这可能是不可能的,但我试图用一个数组创建一个模板类,该数组将其大小设置为我试图用构造函数设置的常量的值.
Tarray(int s): start_size(s){ }
这是设置数组大小的代码:
const int start_size; T this_array[start_size];
这是整个文件:
#ifndef TARRAY_H_ #define TARRAY_H_ template<typename T> class Tarray { private: const int start_size; T this_array[start_size]; int array_size; public: Tarray(int s): start_size(s){ } ~Tarray(){ delete[] this_array; } T & operator[](int i){ return this_array[i]; } }; #endif /* TARRAY_H_ */
这些是我得到的错误:
..\/template_array/Tarray.h:16:24: error: 'Tarray<T>::start_size' cannot appear in a constant-expression ..\/template_array/Tarray.h:16:34: error: 'new' cannot appear in a constant-expression ..\/template_array/Tarray.h:16:34: error: ISO C++ forbids initialization of member 'this_array' [-fpermissive] ..\/template_array/Tarray.h:16:34: error: making 'this_array' static [-fpermissive] ..\/template_array/Tarray.h: In instantiation of 'Tarray<Person>': ..\Human.cpp:17:24: instantiated from here ..\/template_array/Tarray.h:16:34: error: invalid in-class initialization of static data member of non-integral type 'Person*' Build error occurred,build is stopped Time consumed: 343 ms.
当我尝试调整代码时,错误消息一直在变化,但这些是来自此特定构建的错误.
谢谢你的帮助
解决方法
你得到编译器错误的原因是这一行:
T this_array[start_size];
这一行会使你的Tarray实际上包含T的start_size实例.它不会保存指向这些实例的指针或引用 – 它们将是包含Tarray其他实例变量的同一块内存的一部分.
这将使类的大小依赖于start_size,并且在编译时不知道start_size.必须在编译时知道任何C类的大小,这是不可能的.
>使用array new在堆上分配T实例数组.这就是std :: vector的作用.编写这样的类并使其在复制/移动/扩展/等时表现正确是困难和乏味的,所以我建议只使用std :: vector.
>修复T实例的数量,并将其作为模板参数传递
即:
template<typename T,std::size_t N> class TArray { ... T this_array[N]; ... }
这就是std :: array(仅限C 11)和boost :: array.同样,我建议使用其中一种而不是自己编写.除非这是作业,当然……
最后,值得注意的是这是一个错误:
~Tarray(){ delete[] this_array; }
this_array没有分配new,所以你不应该删除它.如果数组是这里的类的一部分(而不是由类分别分配和拥有),那么默认情况下它将与类的其余部分一起销毁.调用删除不仅是不必要的,它几乎肯定会导致崩溃.