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

时间:2019-11-27 20:42:08

标签: c++ pointers reference copy-constructor move-constructor

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

我有一个类Movie,它包含一个字符串名称,字符串等级和受int监视的成员变量。另一类Movies,拥有电影的向量。在电影上,我的方法increment_watched应该将观看的int值增加1,值确实会增加,但似乎该值未保存。电影中的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;
}

1 个答案:

答案 0 :(得分:3)

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