C++ - 更新指针中的值被覆盖

C++ - Updating value in pointer gets overridden

我最近开始学习 C++,但在 Movie class 中更新指针时遇到了一些问题。我感觉我的 Move/Copy 构造函数中某处有问题,但我已经尝试解决这个问题几个小时,交换指向对值的引用的指针,最后来到这里寻求帮助。

我有一个classMovie,其中包含一个字符串名称,字符串评级和int watched成员变量。另一个 class Movies,包含电影的向量。在电影中,我的方法 increment_watched 应该将观看的 int 递增一个,值 确实 递增但似乎该值未保存。 Movies 中的 display_all_movies 方法,它只显示它存储的电影,其中包含已观看的旧值。我知道这个问题可能非常小,但我一直无法弄清楚为什么没有保存该值。

如果有人能解释为什么指针值似乎被覆盖了,我将不胜感激。提前致谢!

代码在下面,里面有一些调试信息。

Movie.h

#ifndef _MOVIE_H_
#define _MOVIE_H_
#include <string>
#include <iostream>

class Movie {
private:
    std::string *name;
    std::string *rating;
    int *watched;
public:
    std::string get_name();
    std::string get_rating();
    int get_watched();
    void increment_watched();
    Movie(std::string name, std::string rating, int watched_val); // normal constructor
    Movie(const Movie &source); // copy constructor
    Movie(Movie &&source); // move constructor
    ~Movie();

};

#endif // _MOVIE_H_

Movie.cpp

#include "Movie.h"

std::string Movie::get_name() {
    return *name;
}

std::string Movie::get_rating() {
    return *rating;
}

int Movie::get_watched() {
    return *watched;
}

void Movie::increment_watched() {
    std::cout << *watched << std::endl;
    (*watched)++; // TODO FIX!
    std::cout << *watched << std::endl;
}

Movie::Movie(std::string name, std::string rating, int watched_val) 
    : name{nullptr}, rating{nullptr}, watched{nullptr}{   
    std::cout << "Creating movie " << watched_val << " with normal constructor" << std::endl; 
    this->name = new std::string{name};
    this->rating = new std::string{rating};
    this->watched = new int{watched_val};

}

Movie::Movie(const Movie &source) 
    : Movie(*source.name, *source.rating, *source.watched) {
        std::cout << "Creating movie " << *source.watched << " with copy constructor" << std::endl; 

}

Movie::Movie(Movie &&source)
    : Movie(*source.name, *source.rating, *source.watched) {
        std::cout << "Creating movie " << *source.watched << " with move constructor" << std::endl; 
        source.name = nullptr;
        source.rating = nullptr;
        source.watched = nullptr;
}

Movie::~Movie() {
        delete name;
        delete rating;
        delete watched;
}

Movies.h

#ifndef _MOVIES_H_
#define _MOVIES_H_
#include <vector>
#include <string>
#include <iostream>
#include "Movie.h"

class Movies {
private:
    static int count;
    std::vector<Movie> *movies;
public:
    void add_movie(std::string &&name, std::string &&rating, int &&watch);
    void increment_movie_count(std::string &&name);
    void display_all_movies();
    void count_movies();
    Movies();
    Movies(const Movie &source); // copy constructor
    Movies(Movie &&source); // move constructor
    ~Movies();

};

#endif // _MOVIES_H_

Movies.cpp

#include "Movies.h"

int Movies::count = 0;

void Movies::add_movie(std::string &&name, std::string &&rating, int &&watch) {
    bool contains {false};

    for(auto movie : *movies) {
        if(movie.get_name() == name) {
            contains = true;
        }
    }
    if(!contains) {
        movies->push_back(Movie{name, rating, watch});
        count++;
    }
}

void Movies::increment_movie_count(std::string &&name) {
    for(auto movie : *movies) {
        if(movie.get_name() == name) {
            movie.increment_watched();
        }
    }

}

void Movies::display_all_movies() {
    for(auto movie : *movies) {
        std::cout << "Title " << movie.get_name() << " Rating " << movie.get_rating() << " Watched " << movie.get_watched() << std::endl;
    }
}

void Movies::count_movies() {
    std::cout << "There are " << count << " movies " << std::endl; 
}

Movies::Movies() {
    movies = new std::vector<Movie>{};
}

Movies::~Movies() {
    delete movies;
}

最后 main.cpp

#include <iostream>
#include "Movies.h"

using std::cout;
using std::endl;

int main() {

    Movies *my_movies;


    my_movies = new Movies();

    (*my_movies).count_movies();

    my_movies->add_movie("Big", "PG-13", 2);
    my_movies->increment_movie_count("Big");

    my_movies->display_all_movies();

    return 0;
}

for(auto movie : *movies)更改为for(auto& movie : *movies)以更新原始电影对象。否则,您只是在更新电影对象的副本。