C++如何正确继承STL容器?继承vector时构造函数匹配报错如何解决
报错核心原因
- 构造函数不会自动继承:C++标准默认不会把父类的构造函数继承到子类中,你自定义
MY_VECTOR后,编译器只会生成默认无参、拷贝、移动三类构造函数,父类vector<vector<int>>的带参构造函数对当前子类不可见,因此传入(n, vector<int>(n))时找不到匹配的构造函数,触发编译报错。 - 存在隐藏的未定义行为:你写的
int n = this->size();、int m = (*this)[0].size();属于成员默认初始化,执行时机在父类构造函数之前,此时父类的vector容器还未完成初始化,调用size()、访问首元素都是非法的内存操作,哪怕构造函数问题解决了,运行时也会出崩溃或异常结果。另外如果后续你调用resize等父类方法修改了容器尺寸,提前存的n、m也会失效,引发逻辑错误。
修复方案
最简修复(推荐)
直接继承父类构造函数,同时把n、m的取值逻辑放到at方法内取实时值,既避免初始化时机问题,也能适配容器动态变化的场景:
#include <iostream> #include <vector> using namespace std; struct MY_VECTOR : public vector<vector<int>> { // 继承父类所有构造函数 using vector<vector<int>>::vector; int at(int i, int j) { // 每次取实时的尺寸,适配容器动态修改的场景 int n = size(); if (n == 0) return 0; int m = (*this)[0].size(); if (i < 0 || j < 0 || i >= n || j >= m) return 0; else return (*this)[i][j]; } }; int main() { int n; cin >> n; MY_VECTOR a(n, vector<int>(n)); // 测试越界访问 cout << a.at(-1, 0) << endl; // 输出0 cout << a.at(0, n) << endl; // 输出0 return 0; }
如果你需要保留n、m作为成员变量
需要自定义构造函数,保证父类构造完成后再给n、m赋值:
struct MY_VECTOR : public vector<vector<int>> { int n, m; // 继承父类其他构造函数 using vector<vector<int>>::vector; // 手动实现你用到的带参构造,初始化n、m MY_VECTOR(size_t n_, const vector<int>& val) : vector<vector<int>>(n_, val) { n = size(); m = n == 0 ? 0 : (*this)[0].size(); } int at(int i, int j) { if (i < 0 || j < 0 || i >= n || j >= m) return 0; else return (*this)[i][j]; } };
注意这种方案下如果你后续调用resize等修改容器尺寸的方法,需要手动更新n、m的值,否则会出现逻辑错误。
内容的提问来源于stack exchange,提问作者Learpcs
相关产品推荐
相关产品推荐

