Recently I've started working on my first OOP project and after having written the program I am trying to optimize it for code efficiency. I want to place the parts of the program that are being copied a lot on the heap.
I can't understand why in certain places objects are copied. An example:
In the main.cpp movies object, which stories movie objects, is created. Add_movie function is called that checks if the movie we are trying to add has already been added, if not, we create a temp object, initialize its private members to the argument values being passed, append it to the vector of the movies object. A copy constructor would be called when movie object is being appended to the vector. WHY? I can't understand the part WHY is it being copied? Is it because of the scope???
If there was an object initialized in the main like
Movie movie1{arguments};
and other movie is created based on movie1
Movie movie2{movie1}.
It makes sense to me, but in the example I gave, it doesn't make sense to me at all
The example of the function I am referring to
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;
}
I don't know if it will help, but there is the code of the program
**main.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;
}
movies.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;}
Debugging the program for hours to see which parts are being copied, when copied, when destructed to get a better grasp.
Watching countless videos that explain the lifetime of the objects, copy constructors, destructors, but it still doesn't make sense for me!