I have the following piece of code:
#include<iostream>
using namespace std;
class A{
int size;
double *arr;
public:
A(int len):size(len)
{
cout<<"ctor called"<<endl;
arr=new double[size];
}
A(const A &rhs)
{
cout<<"calling copy ctor"<<endl;
size=rhs.size;
arr=new double[size];
}
~A()
{
cout<<"calling dtor"<<endl;
delete[] arr;
arr=NULL;
size=0;
}
};
A createVector()
{
cout<<"Creating object"<<endl;
A a(10);
cout<<"returning after creating object a"<<endl;
return a;
}
void foo(A v)
{
cout<<"Class A object rcvd"<<endl;
//return v;
}
int main()
{
A a=createVector();
cout<<"a has been rcvd"<<endl;
foo(a);
return 0;
}
And I have the following output:
Creating object
ctor called
returning after creating object a
a has been rcvd
calling copy ctor
Class A object rcvd
calling dtor
calling dtor
I am having trouble with createVector() function. When I return a object by value,its copy constructor should be called but I am not seeing any output between the lines
returning after creating object a
a has been rcvd
Why copy constructor has not been called??
(when I pass the rcvd object as value to foo(),Copy Constructor gets called)
Related
In the following example I try to create a different object with each constructor call. I wonder how to do it by calling the constructor explicitly?
class A {
public:
static int count;
int num;
A() { num = ++count; }
};
int A::count = 0;
main() {
vector<A> x(5, A()); // all A.num values == 1
vector<A> y(5); // A.num values == 2,3,4,5,6 but no explicit constructor call
}
I want to create member variable sptr of ABC which is object of other class SmartPointer. And then assign value to that member variable.
#include<stdio.h>
#include<iostream>
using namespace std;
class SmartPointer
{
private:
int *ptr;
public:
SmartPointer(int *p);
int& operator *();
~SmartPointer();
};
SmartPointer::SmartPointer(int *p = NULL)
{
cout<<"Initilaize SmartPointer"<<p<< endl;
ptr = p;
}
int& SmartPointer:: operator *()
{
return *ptr;
}
SmartPointer::~SmartPointer()
{
cout<<"De-Initilaize SmartPointer"<<endl;
delete ptr;
}
class ABC
{
private:
int a;
SmartPointer *sptr;
int ref;
public:
ABC(); // Simple constructor.
ABC(int a, int b); // Parameterized constructor.
// ABC(const ABC &obj); // Copy constructor.
~ABC(); // Destructor.
void display(); // Display.
// ABC& operator=(const ABC &obj); // Operator Overload.
};
ABC::ABC()
{
ref= 1;
}
ABC::ABC(int a, int b)
{
cout << "Parameterized constructor input" << endl;
// allocate memory for the pointer;
sptr = new SmartPointer(&a);
cout << "Parameterized constructor Out"<<sptr << endl;
}
ABC::~ABC(void)
{
cout << "Freeing memory!" << endl;
ref --;
if(ref==0)
{
//delete sptr;
}
}
void ABC::display()
{
}
int main()
{
// int a = 10;
// SmartPointer obj1(&a);
// Normal.
ABC obj2(1, 2);
return 0;
}
created sptr = new SmartPointer(&a);, but how to get value of sptr ?
Initially I thought that move constructor will not call the temporary object destructor but when I try it is calling the destructor. So when we steal the data from move constructor I am getting double delete error.
#include <iostream>
using namespace std;
class A
{
public:
A()
: name("default")
{
cout<<"i am default\n";
data = new char[20];
}
A(A&& t)
: name("move")
{
data = t.data;
cout<<"i am move\n";
}
~A()
{
delete data;
cout<<"I am done:"<<name<<endl;
}
char * data;
string name;
};
A getA()
{
A obj;
return obj;
}
int main()
{
A test(std::move(getA()));
}
That's because you are not actually "stealing", you're just copying, and so you'll delete 2 times the same pointer, as you noticed.
To actually "steal" the data, set the original data to nullptr, as it no longer belongs to that object.
A(A&& t)
: name("move")
{
data = t.data;
t.data = nullptr; //'t' doesn't own its data anymore
cout<<"i am move\n";
}
You could also use std::swap (thanks #RemyLebeau):
A(A&& t) : name("move"), data(nullptr)
{
std::swap(data, t.data);
cout << "i am move\n";
}
#include < iostream >
using namespace std;
class A
{
public:
int x;
A(int i)
{
x= i;
cout<<"Constructor is Called "<<x<<endl;
}
~A()
{
cout<<"destructor is Called "<<x<<endl;
}
A(const A &a)
{
cout<<"in copy constructor a.x = "<<a.x<<endl;
cout<<" x = "<<x<<endl;
}
};
const A &fun(int i)
{
cout<<"in Fun"<<endl;
A t(i+1);
return(t);
}
main()
{
A *gg = new A(5);
A t = fun(2);
}
output of this is :
Constructor is Called 5
in Fun
Constructor is Called 3
destructor is Called 3
in copy constructor a.x = 0
x = 4067272
Why it is a.x=0 and x= 4067272?
Add code to initialize x in the copy constructor.
A(const A &a) : x(a.x)
//^^^^^^^^^^^^^^^ Missing code
{
cout<<"in copy constructor a.x = "<<a.x<<endl;
cout<<" x = "<<x<<endl;
}
Also,
fun returns a reference to a local variable. The reference is invalid after you return from fun. When you use A t = fun(2);, you are entering UB territory. You can't assume anything reasonable from it.
You can fix this by returning an object from fun instead of a const&.
A fun(int i)
{
cout<<"in Fun"<<endl;
A t(i+1);
return(t);
}
I found this code on the internet. I am a bit confused about the calling of the copy constructor and I just wanted to know why the copy constructor is called when the display function is called?
#include<iostream>
using namespace std;
class myclass
{
int val;
int copynumber;
public:
//normal constructor
myclass(int i)
{
val = i;
copynumber = 0;
cout<<"inside normal constructor"<<endl;
}
//copy constructor
myclass (const myclass &o)
{
val = o.val;
copynumber = o.copynumber + 1;
cout<<"Inside copy constructor"<<endl;
}
~myclass()
{
if(copynumber == 0)
cout<<"Destructing original"<<endl;
else
cout<<"Destructing copy number"<<endl;
}
int getval()
{
return val;
}
};
void display (myclass ob)
{
cout<<ob.getval()<<endl;
}
int main()
{
myclass a(10);
display (a);
return 0;
}
In the display method you are passing the parameter by value, so obviously there will be a copy made and sent to the function. Learn the difference of pass by value and reference. this and this tutorials may be useful.
It is being invoked because you are passing the object value rather than by const reference. If you passed a const myclass& ob, instead, then the copy constructor wouldn't get called. However, as is, your function is set up to create a copy of the parameter (that is, your function operates on a copy, not the original object).