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

C++中基于指针修正对象间多对多关系的代码修改求助

没问题,我来帮你一步步调整代码,搞定Actor和Movie之间的多对多共享关联问题~核心就是把原来存储对象副本的方式改成存储指针(或者更安全的智能指针),同时在两边维护双向关联,确保同一个Movie能被多个Actor共用。

修改步骤详解

1. 更新Movie类,添加Actor双向关联

首先得让Movie也能记录参演的Actor,这样才是完整的多对多关系。修改后的Movie.hpp如下:

#ifndef MOVIE_H
#define MOVIE_H
#include <vector>
#include <string>
// 前向声明Actor,避免头文件循环引用
class Actor;

class Movie {
private:
    std::string title;
    std::vector<Actor*> actorList; // 存储参演Actor的指针
public:
    std::string getTitle() const {return this->title;}
    void setTitle(std::string newTitle){this->title = newTitle;}
    
    // 添加关联Actor的方法
    void addActor(Actor* actor) {
        actorList.push_back(actor);
    }
    
    // 可选:打印参演演员的方法(后续在cpp文件实现)
    void printActors() const;
};
#endif

2. 改造Actor类,改用Movie指针存储

把原来的std::vector<Movie>改成std::vector<Movie*>,同时修改addMovie方法——不仅要把Movie指针加入自己的列表,还要把当前Actor的指针同步到Movie的演员列表里,确保双向关联生效:

修改后的Actor.hpp:

#ifndef ACTOR_H
#define ACTOR_H
#include "Person.hpp"
#include "Movie.hpp"
#include <vector>
#include <iostream>

class Actor: public Person {
private:
    std::vector<Movie*> movieList; // 替换为Movie指针列表
public:
    void addMovie(Movie* newMovie){
        movieList.push_back(newMovie);
        // 同步把当前Actor加入Movie的演员列表
        newMovie->addActor(this);
    }
    
    void printMovies() {
        for(Movie* movie: this->movieList) { // 遍历指针
            std::cout << movie->getTitle() << '\n'; // 用->访问成员
        }
    }
    
    // 假设Person类有getName方法,这里声明用于后续Movie打印演员
    std::string getName() const;
};
#endif

如果你的Person类里还没有getName()方法,记得在Person.hpp里添加这个成员函数哦。

3. 添加cpp实现文件(解决前向声明的编译问题)

因为我们用了前向声明,涉及到对方类具体成员的方法需要放到cpp文件里实现。创建Movie.cpp:

#include "Movie.hpp"
#include "Actor.hpp"
#include <iostream>

void Movie::printActors() const {
    std::cout << "参演《" << title << "》的演员:\n";
    for(Actor* actor : actorList) {
        std::cout << "- " << actor->getName() << '\n';
    }
}

再创建Actor.cpp(如果需要实现getName的话):

#include "Actor.hpp"

std::string Actor::getName() const {
    // 调用父类Person的getName方法
    return Person::getName();
}

4. 调整Main.cpp的调用逻辑

现在addMovie需要传入Movie的地址,修改后的Main.cpp如下:

#include "Actor.hpp"
#include "Movie.hpp"

int main() {
    Movie movie1, movie2, movie3;
    Actor actor1, actor2;
    
    movie1.setTitle("Transformers");
    movie2.setTitle("Interstellar");
    movie3.setTitle("The Matrix");
    
    actor1.setName("Brad");
    actor1.setAge(57);
    actor1.addMovie(&movie1); // 传入Movie对象的地址
    actor1.addMovie(&movie2);
    
    actor2.setName("Justin");
    actor2.setAge(30);
    actor2.addMovie(&movie3);
    
    // 测试功能
    std::cout << "Brad的参演电影:\n";
    actor1.printMovies();
    
    std::cout << "\n《Transformers》的参演演员:\n";
    movie1.printActors();
    
    return 0;
}

额外优化:用智能指针避免内存问题

如果担心原始指针的悬空、内存泄漏问题,可以用std::shared_ptr和std::weak_ptr替代原始指针(用weak_ptr避免循环引用):

  • Actor类里改成std::vector<std::shared_ptr<Movie>> movieList;
  • Movie类里改成std::vector<std::weak_ptr<Actor>> actorList;
  • Actor需要继承std::enable_shared_from_this<Actor>,才能用shared_from_this()获取自身的智能指针

这个方式更安全,适合复杂场景的内存管理,你可以根据需求选择使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 18:57:46