First off, I apologize if I’m not using the right terms in my question title. It is entirely possible. I am starting to learn c++, and I will admit I’m having a really tough time with references and copies. In reference to my code below, I have the following questions:
-
In main.c, is the argument passed to the Carrier.add() function (*it), a reference, or a copy of the plan object that I put in the vector, or something else?
-
When this argument gets added to the Carrier’s vector of Plans (inside the carrier class), is a copy added? How does that work since I didn’t supply a copy constructor or tell it to make a copy? I think it is automatically generated?
-
Please ignore this one if it is too general. I guess my main problem is that I want/need to understand how it is working, and this is where am having problems trying to find out the answers to my questions on my own. Is there a way to make visual studio generate the constructors in my actual code the same way that the compiler would, so I could step through them in debug mode to see how it all is working. Right now when I debug, it is hard for me to tell that a compiler-generated copy constructor is called (if that is what is happening at all).
Here is my code:
main.c
#include "stdafx.h"
#include <iostream>
#include "Plan.h"
#include "Carrier.h"
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<Plan> plans;
for (int i = 0; i < 4; ++i) {
Plan p(i);
plans.push_back(p);
}
Carrier c(5);
for(std::vector<Plan>::iterator it = plans.begin(); it != plans.end(); ++it) {
//my question is about the line directly below this comment
c.add(*it);
}
return 0;
}
Plan.h
#pragma once
class Plan
{
private:
int id;
public:
Plan(int id);
};
Plan.cpp
#include "Plan.h"
Plan::Plan(int i)
{
id = i;
}
Carrier.h
#pragma once
#include <vector>
class Plan;
class Carrier
{
private:
int id;
std::vector<Plan> plans;
public:
Carrier(int i);
void add(Plan p);
};
Carrier.cpp
#include "Carrier.h"
#include "Plan.h"
Carrier::Carrier(int i) {
id = i;
}
void Carrier::add(Plan p) {
plans.push_back(p);
}
(1) Since
Carrier::adddoes not take its argument by reference, it is passed a copy. To have it take a reference, change its signature to(2) When you do
push_back, a copy is created regardless of whether you pass aPlanby reference or by value/copy; that’s part of the semantics ofstd::vector(and all the other standard containers). The copy constructor is generated automatically by the compiler.(3) I’m not a VC++ user, but the copy constructor that the compiler will generate is equivalent to
In the empty body, you could add a printing statement indicating that the copy constructor is called, but that would not be waterproof; in some cases, C++ is allowed to perform the copy elision optimization, meaning that the actual copying is skipped.