How to create Copy constructor in c++ - c++

I am trying to write a copy constructor for the Shape class, so that it prints the address of the name of s2.
Here is my code:
class Shape {
private:
int x;
int y;
string * name;
public:
//constructor
Shape() {
cout << "Inside the constructor" << endl;
}
//Copy constructor
Shape(Shape& source) {
cout << "Copy constructor called" << endl;
name = new string[name];
copy(source.name, source.name, this->getName);
}
//Destructor
~Shape() {}
void setX(int px) {
x = px;
}
void setY(int py) {
y = py;
}
void setName(string * str) {
name = str;
}
string * getName() {
return name;
}
int main()
{
Shape s1;
s1.setName( new string("first shape") );
Shape s2(s1);
cout << s1.getName() << endl; //will display the address of name for s1
cout << s2.getName() << endl; //will display the address of name for s2
return 0;
}

As you created the string pointer member name for s1 and you're just copying it to s2 when invoking the copy constructor, it's just the expected behaviour that it displays the same address as for s1 - it simply copies the pointer.
If you want a unique name per shape, just create a static method / free function that creates a new name, and call that one in both, constructor and copy constructor, to give each new instance a unique name.
For what it's worth, using the new operator here is not really common (are you coming from a Java background?) - you may just want to use a regular std::string, in which case you don't have to do the memory management yourself (your code basically has a memory leak right now, because you don't call delete anywhere to free the memory allocated via new).
P.S.: Just saw you just edited and changed your code, while I was typing my answer... I won't keep track of the changes (please excuse that), but I leave my answer here for what it's worth.

Could you please try following code?
//Copy constructor
Shape(Shape& source) {
cout << "Copy constructor called" << endl;
name = new string[name];
*name = *source.name;
}

Related

Is there a way to always pass by value (Make a copy) rather than passing by reference when working with class member functions?

For a little background, I have been studying c++ for 3 months so I'm basically a newbie and I'm trying to understand classes that contain raw pointers as data members and how to use copy-contractors and move semantics with them.
So I have this simple class that contains a simple constructor/destructor and an unimplemented copy-constructor.
All I'm doing is creating an object using said class and then calling a member function with it.
So my question is:
Can I somehow always guaranty that when I call a member function I will make a copy of the object calling it and not pass it by reference?
You can easily pass something by reference if you add the "&" operator but what about passing something by value?
I have read that pass by value is the default way the compiler does it but for some reason when I execute my code the copy constructor is not called.
using namespace std;
class dog {
public:
string* name;
int* age;
dog(string NameVal = { "Null" }, int AgeVal = { 10 }) {
name = new string{ NameVal };
age = new int{ AgeVal };
cout << "constructor for " << *name << endl;
}
~dog() {
cout << "destructor for " << *name << " " << age << endl;
}
dog(const dog &source) {
cout << "copy constructor for " << *name << endl;
}
void talk(string text) {
cout << text << *name << endl;
}
};
int main() {
dog test;
test.talk("Test_Text ");
return 0;
}
So I expected the copy constructor to get called for the test object but it looks like it gets passed by reference using the "this" pointer.
How could I change that and actually make a copy of the object when calling the function?
Thanks for any help.
Well, if you want to copy the object and then call a function on the new object then you will need to do it explicitly:
dog test{};
dog{test}.talk("copy talk");
Note that you will also need to actually implement the copy constructor for this to work, otherwise class fields will be left uninitialized:
dog(const dog &source)
: name{new string{*(source.name)}}
, age{new int{*(source.age)}}
{
cout << "copy constructor for " << *name << endl;
}
Is there a way to always pass by value (Make a copy) rather than passing by reference when working with class member functions?
use a static operation receiving the instance by value
class dog {
...
static void talk(dog inst, string text) {
cout << text << *(inst.name) << endl;
}
...
};
int main() {
dog test;
dog::talk(test, "Test_Text ");
// or even
test.talk(test, "Test_Text ");
}

When Does Object Actually Gets Destroyed in C++? What does delete(ptr) Do?

The program without delete works perfectly. However, on using delete, I am not getting any result. The program is terminating abruptly.
#include<iostream>
using namespace std;
class Book
{
string *title;
int *price,*stock;
public:
Book()
{
title=new string();
price=new int();
stock=new int();
}
Book(string n,int p,int s)
{
title=new string(n);
price=new int(p);
stock=new int(s);
}
~Book()
{
cout<<"Object Destroyed"<<endl;
// delete (title); Using Delete i am getting Wrong Results.
// delete (price);
// delete (stock);
}
void inst();
void buy();
void display();
};
void Book::display()
{
cout<<"Title :"<<*title;
cout<<" Price is :"<<*price;
cout<<" Stock is :"<<*stock;
cout<<endl;
}
int main()
{
Book a[2];
for(int x=0;x<2;x++)
{
string title;
int p,s;
cout<<"Enter title,price,stock respectively"<<endl;
cin>>title;
cin>>p;
cin>>s;
a[x]=Book(title,p,s);
}
for(int x=0;x<2;x++)
a[x].display();
}
FOLLOWING IS THE OUTPUT :
Enter title,price,stock respectively
C++
120
2
Object Destroyed
Enter title,price,stock respectively
JAVA
150
5
Object Destroyed
Title :C++ Price is :120 Stock is :2
Title :JAVA Price is :150 Stock is :5
Object Destroyed
Object Destroyed
Why Am I getting Object Destroyed after every input?
Book is not following the Rule of 3/5/0
You have a default constructor and a conversion constructor to allocate memory, and a destructor to free memory, but you do not have a copy constructor or a copy assignment operator (or a move constructor or a move assignment operator). As such, the compiler will provide implicit implementations that shallow-copy the pointers as-is from one object to another, not make deep-copies of the data being pointed at.
This statement:
Book a[2];
Is default-constructing 2 Book objects, and allocating data for each one.
This statement:
a[x]=Book(title,p,s);
Is constructing a temporary Book object for the user's input, then copy-assigning that temporary to an existing object in the array, and then finally destructing the temporary, freeing the memory that it was pointing at.
The compiler-generated copy assignment operator shallow-copies the pointers to the other object (leaking the memory that it was already pointing at), so when the temporary frees the memory, the pointers in the assigned-to object are left dangling. Your code then crashes when display() tries to access invalid memory.
Try this instead:
#include <iostream>
#include <algorithm>
using namespace std;
class Book
{
string *title;
int *price, *stock;
public:
Book() :
title(new string()),
price(new int()),
stock(new int())
{
}
Book(const Book &src) :
title(new string(*src.title)),
price(new int(*src.price)),
stock(new int(*src.stock))
{
}
// C++11 and later only...
Book(Book &&src) :
title(nullptr),
price(nullptr),
stock(nullptr)
{
swap(title, src.title);
swap(price, src.price);
swap(stock, src.stock);
}
Book(string n, int p, int s) :
title(new string(n)),
price(new int(p)),
stock(new int(s))
{
}
~Book()
{
delete title;
delete price;
delete stock;
}
Book& operator=(const Book &rhs)
{
if (&rhs != this)
{
Book tmp(rhs);
swap(title, tmp.title);
swap(price, tmp.price);
swap(stock, tmp.stock);
}
return *this;
}
// C++11 and later only...
Book& operator=(Book &&rhs)
{
swap(title, rhs.title);
swap(price, rhs.price);
swap(stock, rhs.stock);
return *this;
}
...
void display();
};
void Book::display()
{
cout << "Title :" << *title;
cout << " Price is :" << *price;
cout << " Stock is :" << *stock;
cout << endl;
}
The simpler solution is to strive for the Rule of Zero - write code that does not require custom copy/move constructors, copy/move operators, or a destructor. Let the compiler-generated implementations do all of the necessary work for you:
#include <iostream>
using namespace std;
class Book
{
string title;
int price, stock;
public:
Book() :
title(), price(0), stock(0)
{
}
Book(string n, int p, int s) :
title(n), price(p), stock(s)
{
}
...
void display();
};
void Book::display()
{
cout << "Title :" << title;
cout << " Price is :" << price;
cout << " Stock is :" << stock;
cout << endl;
}
With a[x]=Book(title,p,s) the program performs two steps:
Create an instance of Book by using your constructor. Let’s call this instance „alpha“
Create a new instance of Book (a[x]) by using a copy constructor. Let’s call this instance „beta“
When reaching the end of the for brackets, the life line of „alpha“ ends and the destructor is called.
Remember the copy constructor? Using this the pointers are copied. No new instances of the member variables are created. Repugnant the delete part, those member variables are deleted wenn the life line of „alpha“ ends and the corresponding destructor is called. Trying to access the deleted variables still referenced by the pointers of „beta“ causes the crash.
There are multiple solutions to overcome the problem as highlighted in the comments:
Don‘t use pointers
Implement a copy constructor

How are my functions connected to the right member function

so basically I'm learning about game programming from this book, I'm currently on the part where it is explaining where is a data member is a pointer which points to object stored on the heap. it then does a couple of member functions such as destroy/copy or assign to another object.
so basically what I am trying to understand is when i am calling the three functions "testDestructor()"/ "testCopyConstructor(Critter aCopy) " and "testAssignmentOp()" is automatically going to the right member function, it might sound silly but unless I am misreading something, I don't see the book explaining how each fucntion is going to the correct member function.
I don't know its 11:30pm and maybe my brain is melted but I've reread this whole (few pages) detailed explanation of whats going on in the program three times and i cannot make heads or tails of how its correctly using the right member function without some kind of "connection"? perhaps I am missing something rudimentary.
P.S I understand what is happening with the code itself, I just don't know how the functions are calling the correct member functions
/Heap Data Member
//Demonstrates an object with a dynamically allocated data member
#include <iostream>
#include <string>
using namespace std;
class Critter
{
public:
Critter(const string& name = "", int age = 0);
~Critter(); //destructor prototype
Critter(const Critter& c); //copy constructor prototype
Critter& Critter::operator=(const Critter& c); //overloaded assignment op
void Greet() const;
private:
string* m_pName;
int m_Age;
};
Critter::Critter(const string& name, int age)
{
cout << "Constructor called\n";
m_pName = new string(name);
m_Age = age;
}
Critter::~Critter() //destructor definition
{
cout << "Destructor called\n";
delete m_pName;
}
Critter::Critter(const Critter& c) //copy constructor definition
{
cout << "Copy Constructor called\n";
m_pName = new string(*(c.m_pName));
m_Age = c.m_Age;
}
Critter& Critter::operator=(const Critter& c) //overloaded assignment op def
{
cout << "Overloaded Assignment Operator called\n";
if (this != &c)
{
delete m_pName;
m_pName = new string(*(c.m_pName));
m_Age = c.m_Age;
}
return *this;
}
void Critter::Greet() const
{
cout << "I'm " << *m_pName << " and I'm " << m_Age << " years old. ";
cout << "&m_pName: " << cout << &m_pName << endl;
}
void testDestructor();
void testCopyConstructor(Critter aCopy);
void testAssignmentOp();
int main()
{
testDestructor();
cout << endl;
Critter crit("Poochie", 5);
crit.Greet();
testCopyConstructor(crit);
crit.Greet();
cout << endl;
testAssignmentOp();
return 0;
}
void testDestructor()
{
Critter toDestroy("Rover", 3);
toDestroy.Greet();
}
void testCopyConstructor(Critter aCopy)
{
aCopy.Greet();
}
void testAssignmentOp()
{
Critter crit1("crit1", 7);
Critter crit2("crit2", 9);
crit1 = crit2;
crit1.Greet();
crit2.Greet();
cout << endl;
Critter crit3("crit", 11);
crit3 = crit3;
crit3.Greet();
}
I'm not exactly sure what you are asking, but:
The assignment operator is called when you use = in an expression, such as in your code:
crit1 = crit2;
crit3 = crit3;
Not to be confused with using the = symbol in a declaration (which you don't do anyway).
A constructor is called when you try to create an object, such as:
Critter crit2( "crit1", 7 ); // constructor
Other lines might look like:
Critter crit4; // default constructor
Critter crit5(crit3); // copy-constructor
If a constructor takes one argument that is another object of the same type, it's called a copy-constructor. This is just a terminology thing, there's no more fundamental distinction between copy-constructors and other constructors.
In your function void testCopyConstructor(Critter aCopy) , you can see that it has a parameter Critter aCopy. When you pass the argument crit to the function, it is like you create the parameter using the function argument:
Critter aCopy(crit); // equivalent
so calling this function will initialize aCopy using its copy-constructor.
A destructor is called whenever a local object goes out of scope, so when the } is reached at the end of testDestructor, then object toDestroy is destroyed.
what I am trying to understand is when i am calling the three functions "testDestructor()"/ "testCopyConstructor(Critter aCopy) " and "testAssignmentOp()" how is it automatically going to the right member function, it might sound silly but unless I am misreading something, I don't see the book explaining how each fucntion is going to the correct member function.
Instance (non-static) member functions are always passed a hidden pointer as their first argument - explicitly available within the class under the name this - which refers to the target object. This means that when a member function is invoked on/in any instance of a class (object), any in-scope references to member variables will be targeted to this instance via the pointer.
(This well documented and did not really need a new question. Hopefully your book mentions it elsewhere!)

C++ confusion with new and scope

I am trying to learn C++ and from what I've read in books and on SO:
If I use auto x = new Object(); x is a pointer to address of Object and this is in dynamic memory and exists until I delete it.
However if I use Object x; or auto x = Object() it only lasts until it goes out of scope.
In an example they have shown this:
void foo()
{
Point p = Point(0,0);
} // p is now destroyed.
What I don't understand is what happens when I return a object when I don't use new? Will it be a copy of the object?
Here is an example of what I am not sure about:
class Object
{
public:
int X;
static Object Foo(int y)
{
Object result;
result.X = y;
return result;
}
};
class TestContainer
{
public:
void Run()
{
for(auto i = 0; i < 10; i++)
{
_objects.at(i) = Object::Foo(i + (rand() % 10 + 1));
}
}
private:
std::vector<Object> _objects;
};
void main()
{
TestContainer tc;
while(true)
{
tc.Run();
}
}
Note I haven't tested this code but I think it illiterates my confusion. In my main function I instantiate TestContainer and endless call it's Run method. This in turn loops calling a static Foo method on Object that returns a copy of a new Object, which is stored in a vector.
My question is, what happens with all the Object's? If I replace element 2 in the objects vector with a new Object, is the old value now "out of scope" and is deleted?
Will it be a copy of the object?
Yes.
Or a move could be used instead, or the entire thing could be optimised away to produce only one actual object in your final, compiled program.
But, basically, yes.
If I replace element 2 in the objects vector with a new Object, is the old value now "out of scope" and is deleted?
Yes.
As an aside, you're using at on elements that don't exist; to add elements, use insert or push_back.
A simple class like this behaves much like a POD variable. o1=o2 copies the fields, element-wise. So the target Object of an assignment does not get deleted but overwritten.
Objects which go out of scope "go away" (because the stack is unwound) like e.g. an int.
Here is a run-able example that I believe illustrates this behavior:
#include <iostream>
using namespace std;
class Foo {
private:
int id;
public:
Foo(int x)
: id(x)
{
cout << this->id << " is created" << endl;
}
Foo(const Foo& rhs)
: id(rhs.id)
{
cout << "copied " << this->id << endl;
}
Foo& operator=(Foo rhs){
this->id=rhs.id;
cout << "assigned " << this->id << endl;
return *this;
}
~Foo(){
cout << this->id << " is destroyed" << endl;
}
int getID(){
return this->id;
}
};
Foo bar(){
Foo f1 = Foo(1);
cout << f1.getID() << " from bar" << endl;
return f1;
}
int main(){
Foo f2 = bar();
cout << f2.getID() << " from main" << endl;
return 0;
}
This produces this output:
1 is created
1 from bar
1 from main
1 is destroyed
From this, I'm not seeing a copy or an assignment. I suspect what is happening is that both f1 and f2 are referencing the same instance of the object in memory. The object is not being de-allocated when the f1 reference goes out of scope because the object has another reference assigned to it.

Why isn't copy constructor being called like I expect here using map?

I am having problems using my custom class with a std::map. The class dynamically allocates memory for members, and I do not want to use pointer in the map because I want to ensure that the class takes care of deleting all allocated memory. But the problem I am having is after I add item to map, when that block of code goes out of scope, the objects destructor is called even though it is still on the map. I made a fake bit of code below that shows what I mean. The output is: So the problem is why is the final destructor being called? Thanks in advance and sorry for the long question.
Constructor Called Num:0034B7E8
Default Constructor Called Num:00000000
Copy Constructor Called Num:CCCCCCCC
Copy Constructor Called Num:CDCDCDCD
destructor called Num:CCCCCCCC
destructor called Num:00000000
destructor called Num:0034B7E8
Inserted Num:0034B7E8
class myClass
{
public:
myClass(int num)
{
mnNum = new int();
cout << "Constructor Called Num:" << mnNum << endl;
}
myClass() : mnNum(NULL)
{
cout << "Default Constructor Called Num:" << mnNum << endl;
}
myClass(const myClass &copy)
{
mnNum = new int(copy.mnNum);
cout << "Copy Constructor Called Num:" << mnNum << endl;
}
~myClass()
{
delete mnNum;
mnNum = NULL;
}
int* mnNum;
};
map<string,myClass> mvMyMap;
void testFunction()
{
myClass lcObj(1);
mvMyMap["Test"] = lcObj;
}
int _tmain(int argc, _TCHAR* argv[])
{
testFunction();
cout << "Inserted Num:" << mvMyMap["Test"].mnNum << endl;
return 0;
}
myClass needs a custom assignment operator, in addition to the copy constructor. So when you make an assignment, you'll leak the original value on the left, and eventually double delete the value on the right.
Your constructor ignores the num parameter and never initializes mnNum from it. It should look like:
myClass(int num)
{
mnNum = new int(num);
cout << "Constructor Called Num:" << mnNum << endl;
}
You also need to adjust your copy constructor like this:
myClass(const myClass &copy)
{
mnNum = new int(*copy.mnNum);
cout << "Copy Constructor Called Num:" << mnNum << endl;
}
edit
Derek Ledbetter pointed out that we need an assignment operator, too. And I would suggest making the destructor virtual.