子类构造函数传递匿名栈数组至基类失败的解决方法求助
解决匿名栈数组无法传递给基类构造函数的问题
首先咱们先理清问题根源:C++里没法直接把{ {0,1},{0,-1} }这种匿名二维花括号列表传递给int vectors[][2]类型的形参——因为原生数组作为函数参数时会退化为指针,而匿名二维数组是临时对象,没有稳定的内存地址,编译器没法把它转换成int (*)[2]类型的指针。另外,你基类构造函数里origin{ origin }的写法也有问题:如果基类的origin是int[2]数组成员,用指针(形参origin实际是int*)初始化数组是非法的,得手动复制元素。
下面给你几个实用的解决方案:
方案1:使用静态常量数组
把子类要传递的向量定义为静态常量数组,这样它有固定的内存地址,可以安全地传递给基类构造函数,不需要大改现有基类结构:
class Shape { private: int origin[2]; const unsigned int VECTOR_AMOUNT; int (*vectors)[2]; public: Shape(int origin[2], unsigned int vectorAmount, int vectors[][2]) : VECTOR_AMOUNT(vectorAmount) { // 手动复制origin元素,不能直接用origin{origin} this->origin[0] = origin[0]; this->origin[1] = origin[1]; this->vectors = vectors; } }; class I : public Shape { private: // 定义静态常量数组,对应vectorAmount=3的要求 static constexpr int I_VECTORS[][2] = {{0,1}, {0,-1}, {0,0}}; public: I(int origin[]) : Shape(origin, 3, I_VECTORS) {} };
方案2:改用std::vector(推荐)
抛弃原生数组,用C标准库的std::vector存储向量,彻底解决数组退化、临时对象传递的问题,代码更安全易读,是现代C的首选写法:
#include <vector> #include <array> class Shape { private: std::array<int, 2> origin; const unsigned int VECTOR_AMOUNT; std::vector<std::array<int, 2>> vectors; public: Shape(const std::array<int, 2>& origin, const std::vector<std::array<int, 2>>& vectors) : origin(origin), VECTOR_AMOUNT(vectors.size()), vectors(vectors) {} }; class I : public Shape { public: I(const std::array<int, 2>& origin) : Shape(origin, {{0,1}, {0,-1}, {0,0}}) {} // 直接传递初始化列表即可 };
方案3:使用std::array适配固定大小场景
如果你的向量数量是固定的(比如I类固定3个),可以用std::array替代原生二维数组,它不会退化,能直接传递且保留原生数组的性能:
#include <array> class Shape { private: std::array<int, 2> origin; const unsigned int VECTOR_AMOUNT; const std::array<int, 2>* vectors; public: template<size_t N> Shape(const std::array<int, 2>& origin, const std::array<std::array<int, 2>, N>& vectors) : origin(origin), VECTOR_AMOUNT(N), vectors(vectors.data()) {} }; class I : public Shape { public: I(const std::array<int, 2>& origin) : Shape(origin, std::array<std::array<int, 2>, 3>{{{0,1}, {0,-1}, {0,0}}}) {} };
额外提醒
你原来基类构造函数里origin{ origin }的写法是错误的:如果基类origin是int[2]数组,形参origin实际是int*类型,用指针初始化数组是不允许的,必须手动复制每个元素(比如方案1的写法)。如果改用std::array或std::vector,就可以直接用拷贝初始化,不用手动复制了。
内容的提问来源于stack exchange,提问作者Metalhead
相关产品推荐
相关产品推荐

