【问题标题】:Many-to-Many Relationship Between Objects对象之间的多对多关系
【发布时间】:2021-08-26 12:59:44
【问题描述】:

这里是代码 在 Movie.hpp 中

#ifndef MOVIE_H
#define  MOVIE_H

class Movie
{
  private:
    std::string title;
  public:
    std::string getTitle() const {return this->title;}  // const added 
    void setTitle(std::string newTitle){this->title = newTitle;}
};


#endif

在 Actor.hpp 中

#ifndef ACTOR_H
#define  ACTOR_H

#include "Person.hpp"
#include "Movie.hpp"

class Actor: public Person
{
  private:
    std::vector<Movie> movieList;
  public:
    void addMovie(Movie newMovie){this->movieList.push_back(newMovie);}
    void printMovies()
    {
      for(Movie movie: this->movieList)
      {
        std::cout << movie.getTitle() << '\n';
      }
    }
};

#endif

在 Main.cpp 我正在做类似的事情

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); //here
  actor1.addMovie(movie2);

  actor2.setName("Justin");
  actor2.setAge(30);
  actor2.addMovie(movie3);

我被告知我没有遵循多对多关系。换句话说,如果 actor1 和 actor2 与同一部电影有联系,它们应该共享同一个“电影”对象。 就我而言,它们有不同的电影对象。 正确的方法是在 Actor 内部存储指向 Movie 的指针:

std::vector<Movie*> movieList;

(指针的集合,而不是对象的集合)

电影内部:

std::vector<Actor*> actorList;

另一种正确的方法,我更喜欢这个,是添加一个单独的类

class Role {
private:
   Actor* actor;
   Movie* movie;
};

并将此类对象的集合存储在 Movie 和 Actor 中,这里的值(不是指针)是可以的

std::vector<Role> movieList; //inside Actor

std::vector<Role> actorList; //inside Movie

我知道如何解决上述问题,但我无法在使用指针时对上述代码进行更改。有人可以帮我看看当我使用指针时会有什么变化吗?

【问题讨论】:

  • std::vector&lt;Movie&gt; 将创建Movie 对象副本的向量。向量中的每个元素都是其他Movie 对象的副本。并且不同的Movie 对象将是真正不同的,因此对一个对象的修改不会传播到其他副本。解决这个问题的简单方法是使用指针。就像你似乎在做的那样?所以请edit你的问题详细说明你遇到的问题。
  • 听起来您已经有了解决此问题的计划。您在实施Role 理念时是否面临任何具体问题?
  • @NathanPierson 是的,我得到了如何解决该问题的说明,但我无法实施。如果我使用指针,你能帮我看看会有什么变化吗?
  • @Someprogrammerdude 我知道如何解决这个问题,但我在如何实现它时遇到了问题。如果我改用指针,你能告诉我我必须做的改变吗?

标签: c++ object oop many-to-many


【解决方案1】:

您可以使用向量和智能指针。我不知道你用的是哪个版本的c++,但是你可以用std::shared_ptr&lt;Movie&gt;std::shared_ptr&lt;Actor&gt;。每个电影和演员都有自己的共享指针向量。 此类智能指针可从 c++ 11 获得。因此,如果您使用 c++ 11 之前的 c++ 版本,则可以使用 boost 库,其中包括以下智能指针:boost::shared_ptr&lt;Movie&gt;boost::shared_ptr&lt;Actor&gt;

【讨论】:

  • 对不起,java 现在在我的屏幕上。当然,我的意思是 c++ 版本。 boost - 是一个库,允许在早期版本的 c++ 语言中使用一些工具,这些工具在 c++ 的后期版本中可用(如 c++11 或 c++20)。所以我的帖子的总体思路是使用指针向量。第二件事:如果你想避免内存泄漏,你需要管理你分配的 Movie 和 Actor 对象。要么手动完成,要么使用智能指针。
【解决方案2】:

我的建议是有一个电影和演员的主列表,每个都存储为std::shared_ptr 的向量。

然后在 ActorMovie 对象中,您可以拥有彼此的 std::shared_ptr 向量。

所以首先列出主列表:

std::vector<std::shared_ptr<Movie>> master_movies;
std::vector<std::shared_ptr<Actor>> master_actors;

还有课程:

// Forward declaration
class Movie;

class Actor
{
    // ...

public:
    void addMovie(std::shared_ptr<Movie> movie)
    {
        movies.emplace_back(movie);
    }

private:
    // Movies that the actor has been in
    std::vector<std::shared_ptr<Movie>> movies;
};

class Movie
{
    // ...

public:
    void addActor(std::shared_ptr<Actor> actor)
    {
        actors.emplace_back(actor);
    }

private:
    // Actors in this movie
    std::vector<std::shared_ptr<Actor>> actors;
};

始终在主列表中创建演员和电影,并将电影添加到电影主列表中的演员,并将演员添加到演员主列表中的电影:

auto fear = std::make_shared<Movie>();
fear->setTitle("Fear and loathing in Las Vegas");
master_movies.emplace_back(fear);

auto depp = std::make_shared<Actor>();
depp->setName("Johnny Depp");
master_actors.emplace_back(depp);

depp->addMovie(fear);
fear->addActor(depp);

【讨论】:

    猜你喜欢
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多