Why isnt the copy constructor of member class called? - c++

class member
{
public:
member()
{
cout<<"Calling member constr"<<'\n';
}
member(const member&)
{
cout<<"Calling member copy constr"<<'\n';
}
};
class fred
{
public:
fred()
{
cout<<"calling fred constr"<<'\n';
}
fred(const fred &)
{
cout<<"Calling fred copy constr"<<'\n';
}
protected:
member member_;
};
int main()
{
fred a;
fred b=a;
}
Output:
Calling member constr
calling fred constr
**Calling member constr**
Calling fred copy constr

Because you did not call member's copy constructor. You need to copy the members explicitly if you override the default copy constructor of fred.
fred(const fred& other) : member_(other.member_) {
cout<<"Calling fred copy constr"<<'\n';
}

It isn't called because you explicitly asked the compiler not to call it. When you defined your own copy constructor for class fred, you essentially told the compiler that you wanted to take matters into your hands and do the copying yourself. Since you do nothing to copy the member_ in the fred's copy constructor, it isn't copied.
If you get rid of the explicit definition of fred's copy constructor, the compiler will provide an implicit one for you, which will call the member's copy constructor to copy member_.
If you insist on defining fred's copy constructor yourself, you have to copy member_ yourself, as KennyTM suggested.

If class A has a class B member and you explicitly implement the copy ctor for class A, then you must explicitly copy the members there, in this case call the B copy ctor, otherwise the B member will be default constructed, not copy constructed.

You have to explicitly call it in this case. Because, you have overloaded constructors.
Btw, When I see "Fred", it reminds me this useful resource, please have look for further understanding of C++ constructors: http://www.parashift.com/c++-faq-lite/ctors.html

Related

is it possible to forbid assignment if there is no explicit copy constructor? c++

Let's assume I have class with no explicit copy constructor. Is it possible to forbid operation of assigning or copying objects for this class? For example:
class A
{
// data, methods, but no copy constructor and no overloaded assignment operator
};
A object1;
A object2;
object1 = object2; // make compiler error here
A object3 = object1; // or here
You could mark the copy-constructor and copy-assignment operator as deleted:
class A
{
public:
...
A(const A&) = delete;
A& operator=(const A&) = delete;
};
If your compiler doesn't support C++11 features like this, just make the functions private.
Try this
private:
A(A const&); //Don't implement it
A& operator=(A const&);//Don't implement it
or with C++ 11
A(A const&) = delete;
A& operator=(A const&) = delete;
Let's assume I have class with no explicit copy constructor. Is it possible to forbid operation of assigning or copying objects for this class?
Derive it from boost::noncopyable, a base class that is non-copyable, or add a non-static data member that is non-copyable.
If you dont have explicit copy constructor. compiler will create a default one for you.
To forbid copying make copy constructor private.
To forbid assignment make assignment operator private
I also can declare copy constructor or assignment operator without definition. When I call either of them I get linker error.
The implicit copy constructor and assignment operator can only be called if the compiler can generate them. They (conceptually, at least) copy the base class, and then perform memberwise copy of all members. If either of those operations cannot be performed, no implicit copy constructor or assignment operator is generated.
Therefore, you can inhibit these operations by deriving from a non-copyable base class or by including a (non-static) member of a non-copyable type.
As a coding principle, I think it's clearer to explicitly declare the operations as deleted (or private, pre-C++11) members, rather than relying on the presence of a non-copyable member or base class. I'll make an exception if the member/base is named to convey that intent (e.g. boost::noncopyable).
Your question has two part:
First is Explicit constructor, the purpose of explicit constructor is to avoid the implicit construction. By implicit construction I mean
struct C {
int a;
C(int p):a(p) {}
~C(){std::cout<<"Destructor for "<<a<<'\n';}
};
int main() {
C c1 = 142; // implicit-initialization, calls C::C(42)
C c2{12}; //
return 0;
}
But if we make constructor explicit as
explicit C(int a);
Then following code will not compile.
C c1 = 142; // would not compile
This was about the explicit constructor.
Second part is avoiding copy and assignment. So, for that you have two options
As suggested by others,use boost::noncopyable
Remember "The rule of three/five/zero"
http://en.cppreference.com/w/cpp/language/rule_of_three, make your
copy ctor, move ctor & assignment operator as deleted.

copy constructor VS constructor with a class pointer as parameter

Q1: Does the "self class typed pointer constructor" have a decent/official name?
Q2: Why is copy constructor much more famous than "self class typed pointer constructor"?
Or what are the cases that we must use copy constructor rather then "self class typed pointer constructor"?
class MyClass
{
public:
int i;
MyClass()
{
i = 20;
}
//Copy constructor
MyClass(MyClass const & arg)
{
i = arg.i;
}
//What kind of Constructor is this one?
MyClass(MyClass* pArg)
{
i = pArg->i;
}
};
int main() {
MyClass obj;
MyClass* p = new MyClass();
//call copy constructor
MyClass newObj(obj); //call copy constructor directly
MyClass newObj2(*p); //dereference pointer and then call copy constructor
MyClass* pNew = new MyClass(*p); //dereference pointer and then call copy constructor
//Call THE constructor
MyClass theObj(&obj); //get the address, call THE constructor
MyClass theObj2(p); //call pointer constructor directly
MyClass* ptheNew = new MyClass(p); //call pointer constructor directly
}
It has no special name, because there is nothing special about it.
The copy constructor is "more famous", because it is special. It is special because it is a fundamental part of the way the language works. If you don't declare a copy constructor, in most classes, one will be implicitly defined for you. It is involved in many basic operations, such as these:
void foo(MyClass obj) // the copy ctor is (potentially) called to create this parameter
{
...
}
MyClass bar() // the copy ctor is (potentially) called when this function returns, and when it result is used
{
...
}
MyClass a;
MyClass b(a); // This calls the copy constructor
MyClass c = b; // So does this
Note that, in many cases, the copy is optimized away. See Copy Elision. Also, in C++11, the move constructor is called in many places where the copy constructor used to be called. But the move constructor too can be optimized away in the same places that copy elision could happen.
I can't think of many reasons you would ever use "THE constructor", as you call it.
On a side note, a copy constructor should almost always have this signature:
MyClass(MyClass const &)
Not this one:
MyClass(MyClass &)
To an object in C++, we usually use reference rather than pointer. We can use reference to get the address of the object, and than you can use '.' to access its method or data, it is more simple and direct than '->'.
I think there is no need to use 'THE constructor'.

trivial assignment

In trying to understand this answer, it seems that new can be classified as a "copy constructor" and delete sometimes as a "trivial destructor".
I can find next to nothing (that I can quickly grasp) on "trivial assignment" except that it is "trivial if it is implicitly declared, if its class has no virtual member functions or virtual base classes, and if its direct base classes and embedded objects have a trivial assignment operator".
I found a question on yahoo about implicit declaration, but to my surprise, it did not answer.
My brain hurts after reading about virtual member functions.
Besides, I'm a monkey-see-monkey-do programmer, so the only way I'm going to get this is to see it in action. Please explain with respect to the above definition of "trivial" by using the example provided in the first answer, that std::string has a trivial assignment operator by using new or delete or for a less apparent reason.
New can use a copy constructor, and delete uses a destructor. The copy constructor or destructor may be trivial.
That being said, there is a STRONG chance that you will not need to worry about whether a constructor/destructor is trivial for a long time.
new calls a constructor to construct the object. If the one argument to the constructor of type T is an instance of T that is a copy constructor: you are trying to construct an instance of one object from another
class Foo
{
public:
Foo(int x) // not a copy constructor
: mX(x)
{ }
Foo(const Foo& inOther) // copy constructor
: mX(inOther.mX)
{ }
private:
int mX;
};
class Bar
{
public:
Bar(int x)
: mX(x)
{ }
// no copy constructor specified.. C++ will build an implicit one for you
private:
int mX;
}
};
Foo a(1); // uses the first constructor (not a copy)
Foo b(a); // uses a copy constructor
Foo c = a; // copy constructor
Foo* d = new Foo(1); // construct a new instance of Foo (not a copy)
Foo* e = new Foo(a); // copy
Bar f(1); // normal constructor
Bar g(f); // IMPLICIT copy constructor
If your class does not have a copy constructor, like Bar, C++ usually provides you one (always provides you one unless you have an explicit constructor or delete the copy constructor with a C++11 keyword). This copy constructor is very straightforward: it copies each member of your class.
A trivial copy constructor is special. A trivial copy constructor can only be created when the copy constructor is implicitly created for you by the compiler and:
All members of your class are trivially copyable
You do not have any virtual methods or virtual base classes
All of your base classes are trivially copyable.
If you specify a constructor in your class, it is not trivial, by definition. Foo does not have a trivial copy constructor because it is user defined. Bar has an implicit copy constructor because it is not user defined. The implicit copy constructor IS trivial, because copying mX is trivial (copying ints is trivial).
Similar rules go for destructors. A trivial destructor follows the same rules, and delete
WHat does it do for you? The spec lists a few key behaviors about trivial constructors/destructors. In particular, there's a list of things you can do if you have a trivial constructor and destructor that are illegal otherwise. However, they are all very nuanced, and unimportant to 99.9% of C++ code development. They all deal with situations where you can get away with not constructing or destructing an object.
For example, if I have a union:
union MyUnion {
int x;
ClassA y;
ClassB z;
}
If y and z have trivial constructors and destructors, C+ will write a copy constructor for that union for me. If one of them has a non-trivial constructor/destructor, I have to write the copy constructor for the union myself.
Another thing you can do is fast destruction of an array. Usually, when you delete an array, you have to make sure to call the destructor on every item. If you can prove that the destructor of each element is trivial, then you are allowed to skip destroying the elements, and just free the memory. std::vector does this under the hood (so you don't have to)

Copy constructor invocation for member objects

C++ says that to create a copy constructor for a class that uses composition, the compiler recursively calls the copy constructors for all the member objects. I tried that same thing in the below code:
class A
{
public:
A(){cout<<"A constructor called"<<endl;}
A(const A&){cout<<"A copy constructor called"<<endl;}
};
class B
{
public:
B(){cout<<"B constructor called"<<endl;}
B(const B&){cout<<"B copy constructor called"<<endl;}
};
class C
{
A a;
B b;
public:
C(){cout<<"C constructor called"<<endl;}
C(const C&){cout<<"C copy constructor called"<<endl;}// If you comment this line, you will get output: Case 1 (see below) and if you don't comment, you will get o/p: case 2(see below)
};
void main()
{
C c;
cout<<endl;
C c2 = c;
}`
Case 1:
A constructor called
B constructor called
C constructor called
A copy constructor called
B copy constructor called
Case 2:
A constructor called
B constructor called
C constructor called
A constructor called
B constructor called
C copy constructor called
My doubt is that the o/p for case 2 should be: A, B, C, constructor called and then.. A, B, C copy constructor called. But it is not happening. Please help.
That would happen, except that you have provided your own copy constructor for C, which tells the compiler "don't provide the default copy constructor."
If you want your copy constructor to do the same thing that the implicitly defined copy constructor would do (along with your extra printing), you'd need to define it as follows:
C(const C& other)
: a(other.a), b(other.b)
{
std::cout << "C copy constructor called" << std::endl;
}
The standard is only explaining behavior for the default copy constructor. The default copy constructor is the one you're using when you comment out the copy constructor you wrote for C. If you write your own copy constructor you must explicitly copy any members you wish to copy, like so:
C( const C& c ) : a(c.a), b(c.b) {cout<<"C copy constructor called"<<endl;}
Obivously writing your own copy constructor is somewhat error prone, so it's best to rely on the default one whenever possible.
In both cases, C::C( C const &) copy constructor is called. When it is implicit, then it calls copy constructors of base classes. When it is explicit the way you define it, it calls default constructors of A and B. This is expected behavior. Note, C c2 = c; is equal to C c2(c);, there is no temporaries.

C++ implicit copy constructor for a class that contains other objects

I know that the compiler sometimes provides a default copy constructor if you don't implement yourself. I am confused about what exactly this constructor does. If I have a class that contains other objects, none of which have a declared copy constructor, what will the behavior be? For example, a class like this:
class Foo {
Bar bar;
};
class Bar {
int i;
Baz baz;
};
class Baz {
int j;
};
Now if I do this:
Foo f1;
Foo f2(f1);
What will the default copy constructor do? Will the compiler-generated copy constructor in Foo call the compiler-generated constructor in Bar to copy over bar, which will then call the compiler-generated copy constructor in Baz?
Foo f1;
Foo f2(f1);
Yes this will do what you expect it to:
The f2 copy constructor Foo::Foo(Foo const&) is called.
This copy constructs its base class and then each member (recursively)
If you define a class like this:
class X: public Y
{
private:
int m_a;
char* m_b;
Z m_c;
};
The following methods will be defined by your compiler.
Constructor (default) (2 versions)
Constructor (Copy)
Destructor (default)
Assignment operator
Constructor: Default:
There are actually two default constructors.
One is used for zero-initialization while the other is used for value-initialization. The used depends on whether you use () during initialization or not.
// Zero-Initialization compiler generated constructor
X::X()
:Y() // Calls the base constructor
// If this is compiler generated use
// the `Zero-Initialization version'
,m_a(0) // Default construction of basic PODS zeros them
,m_b(0) //
m_c() // Calls the default constructor of Z
// If this is compiler generated use
// the `Zero-Initialization version'
{
}
// Value-Initialization compiler generated constructor
X::X()
:Y() // Calls the base constructor
// If this is compiler generated use
// the `Value-Initialization version'
//,m_a() // Default construction of basic PODS does nothing
//,m_b() // The values are un-initialized.
m_c() // Calls the default constructor of Z
// If this is compiler generated use
// the `Value-Initialization version'
{
}
Notes: If the base class or any members do not have a valid visible default constructor then the default constructor can not be generated. This is not an error unless your code tries to use the default constructor (then only a compile time error).
Constructor (Copy)
X::X(X const& copy)
:Y(copy) // Calls the base copy constructor
,m_a(copy.m_a) // Calls each members copy constructor
,m_b(copy.m_b)
,m_c(copy.m_c)
{}
Notes: If the base class or any members do not have a valid visible copy constructor then the copy constructor can not be generated. This is not an error unless your code tries to use the copy constructor (then only a compile time error).
Assignment Operator
X& operator=(X const& copy)
{
Y::operator=(copy); // Calls the base assignment operator
m_a = copy.m_a; // Calls each members assignment operator
m_b = copy.m_b;
m_c = copy.m_c;
return *this;
}
Notes: If the base class or any members do not have a valid viable assignment operator then the assignment operator can not be generated. This is not an error unless your code tries to use the assignment operator (then only a compile time error).
Destructor
X::~X()
{
// First runs the destructor code
}
// This is psudo code.
// But the equiv of this code happens in every destructor
m_c.~Z(); // Calls the destructor for each member
// m_b // PODs and pointers destructors do nothing
// m_a
~Y(); // Call the base class destructor
If any constructor (including copy) is declared then the default constructor is not implemented by the compiler.
If the copy constructor is declared then the compiler will not generate one.
If the assignment operator is declared then the compiler will not generate one.
If a destructor is declared the compiler will not generate one.
Looking at your code the following copy constructors are generated:
Foo::Foo(Foo const& copy)
:bar(copy.bar)
{}
Bar::Bar(Bar const& copy)
:i(copy.i)
,baz(copy.baz)
{}
Baz::Baz(Baz const& copy)
:j(copy.j)
{}
The compiler provides a copy constructor unless you declare (note: not define) one yourself. The compiler-generated copy constructor simply calls the copy constructor of each member of the class (and of each base class).
The very same is true for the assignment operator and the destructor, BTW. It is different for the default constructor, though: That is provided by the compiler only if you do not declare any other constructor yourself.
Yes, the compiler-generated copy constructor performs a member-wise copy, in the order in which the members are declared in the containing class. If any of the member types do not themselves offer a copy constructor, the would-be copy constructor of the containing class cannot be generated. It may still be possible to write one manually, if you can decide on some appropriate means to initialize the value of the member that can't be copy-constructed -- perhaps by using one of its other constructors.
The C++ default copy constructor creates a shallow copy. A shallow copy will not create new copies of objects that your original object may reference; the old and new objects will simply contain distinct pointers to the same memory location.
The compiler will generate the needed constructors for you.
However, as soon as you define a copy-constructor yourself, the compiler gives up generating anything for that class and will give and error if you don't have the appropriate constructors defined.
Using your example:
class Baz {
Baz(const Baz& b) {}
int j;
};
class Bar {
int i;
Baz baz;
};
class Foo {
Bar bar;
};
Trying to default instantiate or copy-construct Foo will throw an error since Baz is not copy-constructable and the compiler can't generate the default and copy constroctor for Foo.