Why this copy-constructor is invoked in the program? - c++

#include <iostream>
#include <string.h>
using namespace std;
class withCC
{
public:
withCC() {}
withCC(const withCC&) {
cout<<"withCC(withCC&)"<<endl;
}
};
class woCC
{
enum {bsz = 100};
char buf[bsz];
public:
woCC(const char* msg = 0) {
memset(buf, 0, bsz);
if(msg) strncpy(buf, msg, bsz);
}
void print(const char* msg = 0)const {
if(msg) cout<<msg<<":";
cout<<buf<<endl;
}
};
class composite
{
withCC WITHCC;
woCC WOCC;
public:
composite() : WOCC("composite()") {}
void print(const char* msg = 0) {
cout<<"in composite:"<<endl;
WOCC.print(msg);
}
};
int main()
{
composite c;
c.print("contents of c");
cout<<"calling composite copy-constructor"<<endl;
composite c2 = c;
c2.print("contents of c2");
}
The running result is below:
$ ./a.out
in composite:
contents of c:composite()
calling composite copy-constructor
withCC(withCC&)
in composite:
contents of c2:composite()
And I don't understand why withCC(withCC&) is given as part of output. I guess composite c2 = c; causes copy-constructor to be executed. But as below shown, WITHCC is part of class composite, why it will be invoked to handle this copy-constructor? Thanks!

The copy constructor withCC(withCC&) was invoked because the default copy constructor of composite will call all copy constructors of it's member data. And since you have a withCC object as a member data in the composite class, the copy constructor withCC(withCC&) is called.

Copy constructor is called
When instantiating one object and initializing it with values from another object or
When ever you pass an object by value as an argument to a function or
return the object by value from the function
The default copy constructor of composite class will call the copy constructor of its members, that's why withCC(withCC&) is getting printed.

statement composite c2 = c;
will try to copy the object through copy constructor but class composite does not have user defined copy constructor hence default copy constructor of compiler will be used in your case.
And you want to construct WOCC object also with the creation of composite hence for WOCC construction the user define copy constructor of with cc gets called

Related

How the constructor is working within another class

here is a use of static class object inside another class along with a scope resoution operator now i'm not sure whether the static object or the scope resolution operator is the reason that the constuctor from a different class is also invoked.
the code is:
class A
{
public:
A()
{
cout<<"A's constructor"<<endl;
}
};
class B
{
static A a;
public:
B()
{
cout<<"B's constructor";
}
static A get()
{
return a;
}
};
A B :: a;
thus along with the main part
int main()
{
B b;
A a1=b.get();
A a2=b.get();
A a3=b.get();
}
And here is the output:
A's constructor
B's constructor
Another query is that whether the get function is actually doing anything?
Define one more constructor, the copy constructor, in the class A. For example
A( const A & ) { cout << "A's copy constructor" << endl; }
and you will get the following output
A's constructor
B's constructor
A's copy constructor
A's copy constructor
A's copy constructor
That is the first constructor is called to create the static object of the class A die to its definition
A B :: a;
Then within main there is created an object of the type B. And ion these statements
A a1=b.get();
A a2=b.get();
A a3=b.get();
there are created three object of the type A using the copy constructor.

std::map<int, A> operator[] requires the creation of A with empty constructor

#include <map>
class B {
public:
B() {}
};
class A {
public:
A(B b) {
}
};
int main()
{
std::map<int, A> list;
list[0] = A(B());
return 0;
}
The compiler complains that A should have a no-parameter constructor like this: A(){} because of the line list[0] = A(B());. I guess that list[0]; first createas a default A object and then executes the operator=(const A& a) on it so it can copy the A(B()); object.
However I don't want to create a default no-parameter constructor for my A class because it really should be initialized with a B object.
I managed to overcome this by doing
list.insert(std::pair<int, A>(0, A(B()));
Then I noticed that the following line:
A a = list[0];
wouldn't give any errors. For me, A a should create a default A oject using the empty A() constructor which does not exist, then the operator= would be applied. Why this line gives no error?
A a = list[0];
doesn't use a default constructor and the assignment operator. It calls the copy constructor for your class. The copy constructor is implicitly defined.
You get this error because map<>::operator[] instantiates an instance of the value-type (using the default constructor) if the indicated key is not found in the existing object. Due to this being a run-time test map<>::operator[] has to be able to perform that action even if the key is always in fact part of the object.

How to call a parameter constructor of a class that contains a copy constructor as private,in c++?

I have a class that consists of a parameterized constructor which I need to call while creating an object. The class also contains a private copy constructor restricting to create an object to it. Now how to call the paramter constructor of this class. I think we can create a pointer reference to the class. But how to call the parameter constructor using the reference?
My Program:
#include<iostream>
#include<string>
using namespace std;
class ABase
{
protected:
ABase(string str) {
cout<<str<<endl;
cout<<"ABase Constructor"<<endl;
}
~ABase() {
cout<<"ABASE Destructor"<<endl;
}
private:
ABase( const ABase& );
const ABase& operator=( const ABase& );
};
int main( void )
{
ABase *ab;//---------How to call the parameter constructor using this??
return 0;
}
The syntax you need is ABase *ab = new ABase(foo); where foo is either a std::string instance or something that std::string can take on construction, such as a const char[] literal, e.g. "Hello".
Don't forget to call delete to release the memory.
(Alternatively you could write ABase ab(foo) if you don't need a pointer type.)
You can't do this. Because your ctor is protected. Please see (not related with your state, but only to learn more): Why is protected constructor raising an error this this code?

C++ calls default constructor instead of copy constructor

I'm trying to write a program for my Arduino, but I don't understand something that's happening when passing an Item object to another Holder object. I've constructed a simple example:
class Item {
public:
int property;
Item() {
Serial.println("parameterless constructor called");
this->property = 2;
}
Item(int property) {
this->property = property;
Serial.println("right constructor called");
}
};
class Holder {
public:
Item someitem;
Holder(Item& someitem) {
this->someitem = someitem;
}
};
void setup() {
Serial.begin(9600);
Item someitem = Item(1);
Serial.println(someitem.property);
Holder hold = Holder(someitem);
Serial.println(hold.someitem.property);
}
void loop() {
}
The output on the console is:
right constructor called
1
parameterless constructor called
1
I don't understand why the parameterless constructor is called in the first place (I'm not creating a new object to my understanding), and also why it does neither change the current object nor makes a new one. Leaving out the parameterless constructor is prevented by the compiler.
You forgot how we initialize class members in C++ - member initializer lists:
Holder(Item const& someitem) : someitem(someitem) {}
In your code, someitem is default-constructed first (before execution enters the {} block of the constructor), then you're using assignment operator.
Copy constructor is not invoked (and it can't be on already constructed object).

Invoking the copy constructor of a base class for boost pointer containers?

For the below code, when v is copied, the members of Model class do not get copied.
#include <boost/ptr_container/ptr_vector.hpp>
#include <iostream>
using namespace std;
class SomeNewClass
{
public:
int a;
};
class Model
{
public:
int i;
SomeNewClass* s;//A deep copy won't happen here automatically
Model() {}
Model(const Model& m):i(m.i)
{
cout<<"Model Copy ctor invoked"<<endl;
}
};
class ModelInherit : public Model
{
public:
int j;
ModelInherit() {}
ModelInherit(const ModelInherit& m):j(m.j)
{
//i=m.i;//I don't want to copy like this. I want the copy ctor of Model to be invoked
cout<<"ModelInherit Copy ctor invoked"<<endl;
}
};
int main()
{
boost::ptr_vector<ModelInherit> v;
v.push_back(new ModelInherit);
v[0].j = 10;
v[0].i = 20;
v[0].s = new SomeNewClass();
v[0].s->a = 99;
boost::ptr_vector<ModelInherit> v2( v );
cout<< v2[0].j <<endl;
cout<< v2[0].i <<endl;
//cout<< v2[0].s->a <<endl;//segmentation fault
}
What is important to note is that if you comment out the copy constructor of ModelInherit, then the pointer container automatically copies the i variable in the Model class. Sad part is that "SomeNewClass* s" does not get copied. No deep copy.
So my questions are:
Do you know how to invoke the copy
constructor of the Model class in the
above code?
How do I ensure a deep copy when the pointer container is automatically copying variables so that even the 'a' variable of SomeNewClass gets copied?
(1) To invoke Model copy constructor, change your ModelInherit copy constructor like following:
ModelInherit(const ModelInherit& m): Model(m), j(m.j) {}
(2) Deep copy can be done like this:
Model(const Model& m): i(m.i), s(0)
{
if(m.s != 0)
this->s = new SomeNewClass(*(m.s));
cout<<"Model Copy ctor invoked"<<endl;
}
And declare a copy constructor for SomeNewClass like below:
SomeNewClass(const SomeNewClass &copy) : a(copy.a)
{
cout<<"SomeNewClass Copy ctor invoked"<<endl;
}
Don't forget to free Model::s in destructor, otherwise it will leak memory:
~Model () { delete this->s; } // it's ok if s = 0
Invoking base class copy-constructor is easy:
ModelInherit(const ModelInherit& m): Model(m), j(m.j) {}
//^^^^^^^^ note this
Model(m) invokes base class copy-constructor; the parameter m implicitly converts into base class.
In the base class copy-constructor, you've to manually deep-copy m.s.