复制构造函数和动态内存C++ [已关闭]

ajsxfq5m  于 2023-02-01  发布在  其他
关注(0)|答案(1)|浏览(111)

编辑问题以包含desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem。这将有助于其他人回答问题。
3天前关闭。
Improve this question
最近我开始了我的第一个OOP项目,在写好程序之后,我试图优化它以提高代码效率,我想把程序中被大量复制的部分放在堆中。
我不明白为什么在某些地方物品会被复制。举个例子:
在main.cpp movies对象中,创建了故事电影对象。调用Add_movie函数,检查我们试图添加的电影是否已经添加,如果没有,则创建一个临时对象,将其私有成员初始化为正在传递的参数值。将其附加到电影对象的向量。当电影对象被附加到向量时,将调用复制构造函数。为什么?我不能'I don "我不明白为什么要复制它?是因为范围的原因吗?
如果在main中初始化了一个对象

Movie movie1{arguments};

并且基于电影1创建其它电影

Movie movie2{movie1}.

这对我来说是有意义的,但在我给出的例子中,这对我来说根本没有意义
我所指的函数的示例

bool Movies::add_movie(std::string name, std::string rating, int watched)
{
    for (const Movie& obj : movies_list)
    {
        if (obj.get_name() == name) // search for a match
        {
            return false; // if found stop executing
        }
    }
    Movie temp{ name, rating, watched }; // creates a new object and initializes its private members to the passed arguments
# movies_list.push_back(temp); // appends the object to the vector
# ***    return true;
}

我不知道这是否有用,但这是程序代码

    • 主. cpp**
#include "Movie.h"
#include "Movies.h"

#include <iostream>
#include <string>

void add_movie(Movies& obj, std::string name, std::string rating, int watched)
{
    if (obj.add_movie(name, rating, watched))
    {
        std::cout << name << " succesfully added" << std::endl;
    }
    else
    {
        std::cout << name << " already has been added" << std::endl;
    }
}
// if the parent increment_watched function returns true, inform the user about the result of the operation
void increment_watched(Movies &obj, std::string name)
{
    if (obj.increment_watched(name)) // if Movies::increment_watched returns
    {
        std::cout << name << " watch count succesfully incremented by 1" << std::endl;
    }
    else {
        std::cout << name << " movie not found" << std::endl;
    }
}

int main()
{

    Movies list;

    add_movie(list, "Fight Club", "A", 1);
    add_movie(list, "Fight Club", "A", 1);
    add_movie(list, "Inception", "A", 1);

    increment_watched(list, "Fight Club");
    increment_watched(list, "Else Test");
    

    list.display();

    return 0;
}
    • 电影. cpp**
#include "Movie.h"
#include "Movies.h"

#include <iostream>

bool Movies::add_movie(std::string name, std::string rating, int watched)
{
    for (const Movie& obj : movies_list)
    {
        if (obj.get_name() == name) // search for a match
        {
            return false; // if found stop executing
        }
    }
    Movie temp{ name, rating, watched }; // creates a new object and initializes its private members to the passed arguments
    movies_list.push_back(temp); // appends the object to the vector
    return true;
}
void Movies::display() const
{
    if (movies_list.size() == 0) // checks the vector size
    {
        std::cout << "The list is empty" << std::endl;
    }
    else
    {
        std::cout << "\nThe list of the movies: " << std::endl;
        std::cout << "----------------------------" << std::endl;

        for (const Movie& obj : movies_list) 
        {
            obj.display_members(); // accesses the private members of the object that are stored in the vector and outputs them to the user
        }
    }
}
bool Movies::increment_watched(std::string name)
{
    for (Movie &obj : movies_list) // iterates through the movie objects until finds the match in name
    {
        if (obj.get_name() == name)
        {
            obj.increment_watched(); // increments watched by 1 
            return true;
        }
    }
    return false;
}

movie.cpp

#include <string>
#include <iostream>
#include "Movie.h"

// constructor for initializing private members of the object
Movie::Movie(std::string name, std::string rating, int watched)
{
    this->name = name;
    this->rating = rating;
    this->watched = watched;
}
// get methods
std::string Movie::get_name() const { return name; }
std::string Movie::get_rating() const { return rating; }
int Movie::get_watched() const { return watched; }

// display private members
void Movie::display_members() const
{
    std::cout << "Name: " << get_name() << std::endl;
    std::cout << "Rating: " << get_rating() << std::endl;
    std::cout << "Times watched: " << get_watched() << std::endl;
    std::cout << "\n" << std::endl;
}
// setter function
void Movie::increment_watched() {watched++;}

// DEBUGGING
Movie::Movie(const Movie &obj):name{obj.name}, rating{obj.rating}, watched{obj.watched} {std::cout << "copy constructor called for " << name << std::endl;}
Movie::~Movie() {std::cout << "destructor called for movie " << name << std::endl;}

调试程序几个小时,看看哪些部分被复制,什么时候复制,什么时候破坏,以获得更好的把握。
看了无数的视频,解释对象的生命周期,复制构造函数,析构函数,但它仍然没有意义!

e0bqpujr

e0bqpujr1#

push_back()获取一个对象并将其追加到vector的末尾。它必须进行复制,因为它必须保持原始对象的完整性,因为您以后可能会需要它。如果您想避免复制,您必须使用std::move来触发move构造函数。

movies_list.push_back(std::move(temp));

然而,在您的示例中,您基本上想要在向量的末尾 * 构造 * 一个对象。emplace_back正是您所需要的;没有复制或移动,只是传递构造函数参数。

movies_list.emplace_back(name, rating,watched);

相关问题