首页 > 解决方案 > C++ - 更新指针中的值被覆盖

问题描述

我最近开始学习 C++,但在更新Movie课堂上的指针时遇到了一些麻烦。我有一种感觉,我的 Move/Copy 构造函数的某个地方有问题,但一直试图解决这个问题几个小时,交换指向值的引用的指针,最后来这里寻求帮助。

我有一个类Movie,其中包含一个字符串名称、字符串等级和 int 监视的成员变量。另一个类Movies,包含电影的向量。在电影上,我的方法increment_watched应该将观看的 int 增加一,值确实增加了,但似乎没有保存该值。Movies 中的display_all_movies方法,它简单地显示它存储的电影,保留旧的观看值。我知道问题可能很小,但我无法弄清楚为什么没有保存价值。

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

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

电影.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_

电影.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;
}

电影.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_

电影.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;
}

标签: c++pointersreferencecopy-constructormove-constructor

解决方案


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


推荐阅读