You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++98中StorageConnection对象无法填充Controller向量问题

问题排查:嵌套类vector容器数据无法存入的原因及解决办法

问题描述

我创建了多层嵌套类,每个类都包含对应对象的vector容器。尝试把已填充数据的vector<Controller>添加到StorageConnection对象时,发现对象里没存入任何Controller数据。确认添加前controllerListTemp有有效数据,但执行复制后,storageConnectionTemp.getFileSystem(0).getControllerListSize()一直返回0。项目基于C++98开发,不能用新版本特性。

相关类定义代码

class Host
{
public: 
    Host () : hostName_("") { }
    // setters and getters for hostName_
private:
    string hostName_;
};

class Controller
{
public: 
    Controller() : controllerName_(""), hostList_() { }
    int getHostListSize() {...}
    Host getHost( int index ) { return hostList_.at(index); }
    Host getHost( string hostName ) {...}
    vector<Host> getHostList() { return hostList_;}
    void addToHostList(Host host) { hostList_.push_back(host); }
    void clearHostList() { hostList_.clear(); }
    // setters and getters for controllerName_
private:
    string controllerName_;
    vector<Host> hostList_;
};

class FileSystem
{
public: 
    FileSystem() : fileSystemName_(""), controllerList_() { }
    int getControllerListSize() {...}
    Controller getController( int index ) { return controllerList_.at(index); }
    Controller getController( string controllerName ) {...}
    vector<Controller> getControllerList() { return controllerList_;}
    void addToControllerList(Controller controller) { controllerList_.push_back(controller); }
    void clearControllerList() { controllerList_.clear(); }

    // setters and getters for fileSystemName_
private:
    string fileSystemName_;
    vector<Controller> controllerList_;
};

class StorageConnection
{
public: 
    StorageConnection() : siteName_(""), fileSystemList_() { }

    int getFileSystemListSize() {...}
    FileSystem getFileSystem ( int index ) { return fileSystemList_.at(index); }
    FileSystem getFileSystem ( string fileSystemName) {...}
    vector<FileSystem> getFileSystemList() { return fileSystemList_;}
    void addToFileSystemList(FileSystem fileSystem) { fileSystemList_.push_back(fileSystem); }
    void clearFileSystemList() { fileSystemList_.clear(); }

    // setters and getters for siteName_
private:
    string siteName_;
    vector<FileSystem> fileSystemList_;
};

填充方法代码

void populateStorageConnection()
{
    vector<Controller> controllerListTemp; 
    StorageConnection storageConnectionTemp;
    
 // 已完成controllerListTemp和storageConnectionTemp中fileSystemList的填充
// 将controllerList添加至storageConnectionTemp对象
    for ( int controllerCounter = 0; controllerCounter < controllerListTemp.size(); controllerCounter++ )
    {
       storageConnectionTemp.getFileSystem(0).addToControllerList(controllerListTemp.at(controllerCounter));
       
    }

}

问题原因

核心问题在于所有getter方法返回的是对象副本,而非原容器内对象的引用:

  • StorageConnection::getFileSystem(int)返回的是FileSystem对象的副本,不是fileSystemList_容器里的原对象
  • 调用storageConnectionTemp.getFileSystem(0).addToControllerList(...)时,实际是在临时副本上添加数据,副本执行完代码后就被销毁,原storageConnectionTemp内的FileSystem对象完全没被修改
  • 同理,其他类如Controller的getter方法也存在返回副本的问题,但本次直接触发问题的是getFileSystem的返回值特性

解决办法

方法1:新增返回引用的getter方法

修改类定义,添加返回非const引用的getter(用于修改原对象),同时保留原有的返回副本的getter(用于只读场景):

class StorageConnection
{
public: 
    // 新增:返回引用,用于修改原对象
    FileSystem& getFileSystemRef(int index) { return fileSystemList_.at(index); }
    FileSystem& getFileSystemRef(string fileSystemName) { /* 实现逻辑:找到对应对象并返回引用 */ }

    // 原有只读getter保留
    FileSystem getFileSystem(int index) { return fileSystemList_.at(index); }
    // ... 其他原有代码
};

class FileSystem
{
public:
    // 同理新增返回引用的getter
    Controller& getControllerRef(int index) { return controllerList_.at(index); }
    Controller& getControllerRef(string controllerName) { /* 实现逻辑 */ }
    // ... 其他原有代码
};

修改填充代码,使用引用getter操作原对象:

for (int controllerCounter = 0; controllerCounter < controllerListTemp.size(); controllerCounter++)
{
    storageConnectionTemp.getFileSystemRef(0).addToControllerList(controllerListTemp.at(controllerCounter));
}

方法2:添加批量操作的成员函数

在FileSystem类中添加直接接收vector<Controller>的批量添加方法,同时在StorageConnection中封装直接操作指定FileSystem的接口,避免通过getter接触对象:

class FileSystem
{
public:
    void addAllToControllerList(const vector<Controller>& controllers)
    {
        for (size_t i = 0; i < controllers.size(); ++i)
        {
            controllerList_.push_back(controllers[i]);
        }
    }
    // ... 其他原有代码
};

class StorageConnection
{
public:
    void addAllControllersToFileSystem(int fsIndex, const vector<Controller>& controllers)
    {
        fileSystemList_.at(fsIndex).addAllToControllerList(controllers);
    }
    // ... 其他原有代码
};

填充代码简化为:

storageConnectionTemp.addAllControllersToFileSystem(0, controllerListTemp);

补充说明

如果仅需读取数据,原有的返回副本的getter完全可用;但如果要修改容器内的对象,必须使用返回引用的getter或直接封装操作接口,否则所有修改都只会作用在临时副本上,原数据不会有任何变化。

内容的提问来源于stack exchange,提问作者Llama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 14:15:26