如何让C++派生类对象共享基类的static vector<int>成员
解决派生类对象共享静态成员vector的问题
问题情况
你定义了base基类和derived派生类,想让两个derived对象共用同一个静态成员myVec,但创建第二个对象时,之前修改的myVec被重新初始化了,导致obj2输出全0,不是你想要的1 0 0 0 0。
你的代码如下:
基类base
class base { protected: static vector <int> myVec; // 声明静态vector public: base(int x) { // 将vector初始化为大小x myVec.resize(x); for (int i = 0; i < x; i++) { // 为每个索引赋值0 myVec[i] = 0; } } };
派生类derived
class derived : public base { public: derived(int x) : base {x} {} void editVec(int pos) { myVec[pos] = 1; // 将指定位置赋值为1 } void printVec() { // 遍历vector并输出到控制台 for (int i = 0; i < myVec.size(); i++){ cout << myVec[i] << " "; } cout << endl; } };
测试代码
int main() { derived obj1(5); // 创建derived实例 obj1.editVec(0); // 修改myVec的0号位置为1 obj1.printVec(); // 输出1 0 0 0 0 derived obj2(5); // 创建第二个derived实例 obj2.printVec(); // 输出0 0 0 0 0,不符合预期 return 0; }
问题出在哪
静态成员myVec本身确实是所有对象共享的,但base的构造函数每次被调用,都会把myVec改成指定大小,还把所有元素重新设为0。创建obj2的时候,又跑了一遍base的构造函数,直接把obj1改的内容覆盖了。另外,你还漏了静态成员的类外定义,这会导致链接报错,必须补上。
解决办法
1. 补上静态成员的类外定义
C++里静态成员只在类里声明还不够,必须在类外(一般写在cpp文件里)定义,不然链接会失败。加一行代码:
vector<int> base::myVec; // 静态成员的类外定义
2. 修改base的构造函数,别重复初始化
让构造函数只在myVec是空的时候才做初始化,后面创建对象就不要再重置了:
修改后的base构造函数:
base(int x) { if (myVec.empty()) { // 只有vector没初始化过的时候才执行初始化 myVec.resize(x, 0); // 用resize的第二个参数直接设为0,比循环省事 } else if (myVec.size() != x) { // 可选:如果后面创建对象给的大小不一样,这里可以抛异常提示 throw std::invalid_argument("不能创建大小和已有静态vector不一样的对象"); } }
改完后的效果
再跑main函数,obj2.printVec()就会输出1 0 0 0 0了。因为obj2构造的时候,myVec已经被obj1初始化好了,不会再重置,之前的修改就保留下来了。
额外选项
如果你需要允许后续扩展myVec的大小但不重置已有元素,可以改成这样:
base(int x) { if (myVec.size() < x) { myVec.resize(x, 0); // 只有当前大小不够时才扩展,新元素设为0 } }
这个得看你实际需求来选,确保所有对象对myVec的操作都符合预期。
内容的提问来源于stack exchange,提问作者Mazda Man
相关产品推荐
相关产品推荐

