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

如何让C++中第二个Vector存储原对象引用以同步修改原对象?

问题描述

我正在把Java代码里的性能关键部分转成C++。Java里往第二个List添加原List的对象时只存储引用,修改子List里的对象会同步影响原List的对应对象;但C里用push_back往子Vector添加对象会执行深拷贝,导致修改子Vector的对象无法影响原Vector的对象。以下是Java和C的示例代码,请问如何修改C++代码使其输出为true?

Java示例代码

class Data {
    Data(int id){
        this.id = id;
        this.name = "Name " + id;
    }
    public int id;
    public String name = "";
    public boolean isFancy = false;
}

public class Main {
    public static void main(String[] args) {
        List<Data> dataList = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            Data data = new Data(i);
            dataList.add(data);
        }

        List<Data> dataSublist = new ArrayList<>();
        dataSublist.add(dataList.get(2));
        dataSublist.add(dataList.get(3));
        dataSublist.add(dataList.get(8));
        dataSublist.forEach(data -> data.isFancy = true); // 修改子List中的对象会同步影响原对象

        System.out.println("Data 3 original isFancy = " + dataList.get(3).isFancy); // 输出true
    }
}

原C++示例代码(输出false)

class Data {
public:
    Data(int id) { id_ = id; };

    int id_ = 0;
    std::string name_ = "";
    bool isFancy_ = false;
};

int main()
{
    std::vector<Data> dataList;

    for (int i = 0; i < 10; i++) {
        Data data = Data(i);
        dataList.push_back(data);
    }

    std::vector<Data> dataSublist;
    dataSublist.push_back(dataList[2]);
    dataSublist.push_back(dataList[3]);
    dataSublist.push_back(dataList[8]);
    for (int i = 0; i < dataSublist.size(); i++) {
        dataSublist[i].isFancy_ = true; // 修改子Vector的对象不会影响原对象
    }

    std::cout << "Data 3 original isFancy = " << ((dataList[3].isFancy_) ? "true" : "false"); // 输出false
}

解决方案

要让C++实现Java式的对象引用共享,核心是让子Vector存储原对象的引用或指针,而非对象副本。以下是几种可行方案:

方案1:使用智能指针(推荐,安全无内存泄漏)

用std::shared_ptr自动管理对象内存,同时实现多容器共享同一对象。

#include <vector>
#include <iostream>
#include <string>
#include <memory>

class Data {
public:
    Data(int id) : id_(id), name_("Name " + std::to_string(id)) {};

    int id_ = 0;
    std::string name_ = "";
    bool isFancy_ = false;
};

int main()
{
    std::vector<std::shared_ptr<Data>> dataList;

    // 直接创建智能指针并加入容器,避免拷贝
    for (int i = 0; i < 10; i++) {
        dataList.push_back(std::make_shared<Data>(i));
    }

    std::vector<std::shared_ptr<Data>> dataSublist;
    // 存储原容器中对象的智能指针,共享同一对象
    dataSublist.push_back(dataList[2]);
    dataSublist.push_back(dataList[3]);
    dataSublist.push_back(dataList[8]);
    
    // 修改子容器中的指针指向的对象,直接作用于原对象
    for (auto& dataPtr : dataSublist) {
        dataPtr->isFancy_ = true;
    }

    std::cout << "Data 3 original isFancy = " << ((dataList[3]->isFancy_) ? "true" : "false") << std::endl;
    // 输出true,无需手动释放内存,智能指针会自动处理
}

方案2:使用原始指针(性能最优,需手动管理内存)

如果追求极致性能且能确保内存安全,可以使用原始指针,但要注意手动释放内存避免泄漏。

#include <vector>
#include <iostream>
#include <string>

class Data {
public:
    Data(int id) : id_(id), name_("Name " + std::to_string(id)) {};

    int id_ = 0;
    std::string name_ = "";
    bool isFancy_ = false;
};

int main()
{
    std::vector<Data*> dataList;

    // 动态分配对象,存储指针
    for (int i = 0; i < 10; i++) {
        dataList.push_back(new Data(i));
    }

    std::vector<Data*> dataSublist;
    dataSublist.push_back(dataList[2]);
    dataSublist.push_back(dataList[3]);
    dataSublist.push_back(dataList[8]);
    
    for (auto dataPtr : dataSublist) {
        dataPtr->isFancy_ = true;
    }

    std::cout << "Data 3 original isFancy = " << ((dataList[3]->isFancy_) ? "true" : "false") << std::endl;

    // 手动释放所有动态分配的内存
    for (auto dataPtr : dataList) {
        delete dataPtr;
    }
}

方案3:使用引用包装器(无指针,C++11及以上)

用std::reference_wrapper将对象引用包装为可拷贝类型,存储在Vector中,既避免拷贝又无需管理内存。

#include <vector>
#include <iostream>
#include <string>
#include <functional> // 包含std::reference_wrapper

class Data {
public:
    Data(int id) : id_(id), name_("Name " + std::to_string(id)) {};

    int id_ = 0;
    std::string name_ = "";
    bool isFancy_ = false;
};

int main()
{
    std::vector<Data> dataList;

    // 直接在容器内构造对象,避免拷贝
    for (int i = 0; i < 10; i++) {
        dataList.emplace_back(i);
    }

    std::vector<std::reference_wrapper<Data>> dataSublist;
    // 存储原对象的引用包装
    dataSublist.push_back(dataList[2]);
    dataSublist.push_back(dataList[3]);
    dataSublist.push_back(dataList[8]);
    
    // 通过get()获取原对象引用并修改
    for (auto& dataRef : dataSublist) {
        dataRef.get().isFancy_ = true;
    }

    std::cout << "Data 3 original isFancy = " << ((dataList[3].isFancy_) ? "true" : "false") << std::endl;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:15:27