Rectangle 27 86

You can explicitly call constructors and assignment operators:

class Base {
//...
public:
    Base(const Base&) { /*...*/ }
    Base& operator=(const Base&) { /*...*/ }
};

class Derived : public Base
{
    int additional_;
public:
    Derived(const Derived& d)
        : Base(d) // dispatch to base copy constructor
        , additional_(d.additional_)
    {
    }

    Derived& operator=(const Derived& d)
    {
        Base::operator=(d);
        additional_ = d.additional_;
        return *this;
    }
};

The interesting thing is that this works even if you didn't explicitly define these functions (it then uses the compiler generated functions).

class ImplicitBase { 
    int value_; 
    // No operator=() defined
};

class Derived : public ImplicitBase {
    const char* name_;
public:
    Derived& operator=(const Derived& d)
    {
         ImplicitBase::operator=(d); // Call compiler generated operator=
         name_ = strdup(d.name_);
         return *this;
    }
};
Base(const Base&)

@CravingSpirit it's a copy constructor (with the argument name omitted).

Thanks. Why do we need a copy constructor if there is already a operator= overloading?

@CravingSpirit they are used in different situations, this is basic C++ I suggest you read a bit more about it.

@qed copy constructor is used for initialization, while assignment operator used in assignment expression.

inheritance - How to use base class's constructors and assignment oper...

c++ inheritance constructor assignment-operator
Rectangle 27 16

Short Answer: Yes you will need to repeat the work in D

If your derived class 'D' contains no new member variables then the default versions (generated by the compiler should work just fine). The default Copy constructor will call the parent copy constructor and the default assignment operator will call the parent assignment operator.

B(const B& b){(*this) = b;}

D(const D& d){(*this) = d;}

Normally copy constructors chain so that they are copy constructed from the base up. Here because you are calling the assignment operator the copy constructor must call the default constructor to default initialize the object from the bottom up first. Then you go down again using the assignment operator. This seems rather inefficient.

Now if you do an assignment you are copying from the bottom up (or top down) but it seems hard for you to do that and provide a strong exception guarantee. If at any point a resource fails to copy and you throw an exception the object will be in an indeterminate state (which is a bad thing).

Normally I have seen it done the other way around. The assignment operator is defined in terms of the copy constructor and swap. This is because it makes it easier to provide the strong exception guarantee. I don't think you will be able to provide the strong guarantee by doing it this way around (I could be wrong).

class X
{
    // If your class has no resources then use the default version.
    // Dynamically allocated memory is a resource.
    // If any members have a constructor that throws then you will need to
    // write your owen version of these to make it exception safe.


    X(X const& copy)
      // Do most of the work here in the initializer list
    { /* Do some Work Here */}

    X& operator=(X const& copy)
    {
        X tmp(copy);      // All resource all allocation happens here.
                          // If this fails the copy will throw an exception 
                          // and 'this' object is unaffected by the exception.
        swap(tmp);
        return *this;
    }
    // swap is usually trivial to implement
    // and you should easily be able to provide the no-throw guarantee.
    void swap(X& s) throws()
    {
        /* Swap all members */
    }
};

Even if you derive a class D from from X this does not affect this pattern. Admittedly you need to repeat a bit of the work by making explicit calls into the base class, but this is relatively trivial.

class D: public X
{

    // Note:
    // If D contains no members and only a new version of foo()
    // Then the default version of these will work fine.

    D(D const& copy)
      :X(copy)  // Chain X's copy constructor
      // Do most of D's work here in the initializer list
    { /* More here */}



    D& operator=(D const& copy)
    {
        D tmp(copy);      // All resource all allocation happens here.
                          // If this fails the copy will throw an exception 
                          // and 'this' object is unaffected by the exception.
        swap(tmp);
        return *this;
    }
    // swap is usually trivial to implement
    // and you should easily be able to provide the no-throw guarantee.
    void swap(D& s) throws()
    {
        X::swap(s); // swap the base class members
        /* Swap all D members */
    }
};

+1. Since you are at it, add an specialization to std::swap for your type that delegates on your swap member method: 'namespace std { template<> void std::swap( D & lhs, D & rhs ) { lhs.swap(rhs); } }' This way the specialized swap operation can be used in STL algorithms.

Adding a free swap function in the same namespace as X should have the same effect (via ADL), but someone was saying recently that MSVC incorrectly calls std::swap explicitly, thus making dribeas right...

Also technically you are not allowed to add stuff to the standard namespace.

You are allowed to specialize standard algorithms in std for user-defined types. dribeas' code is valid, it's just that the gurus seem to recommend the ADL solution.

inheritance - How to use base class's constructors and assignment oper...

c++ inheritance constructor assignment-operator
Rectangle 27 10

In case your class contains only vector/string objects as its data members, you don't need to implement these. The C++ STL classes (like vector, string) have their own copy ctor, overloaded assignment operator and destructor.

But in case if your class allocates memory dynamically in the constructor then a naive shallow copy will lead to trouble. In that case you'll have to implement copy ctor, overloaded assignment operator and destructor.

Under what circumstances must I provide, assignment operator, copy con...

c++ destructor copy-constructor assignment-operator
Rectangle 27 4

One common way is the copy-and-swap idiom. You would have to implement a swap operation, but if done correctly, you have the additional benefit of having exception safe assignment.

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

in C++, How can I give a class copy constructor and assignment operato...

c++ constructor copy-constructor code-duplication assignment-operator
Rectangle 27 5

The usual rule of thumb says: if you need one of them, then you need them all.

Not all classes need them, though. If you class holds no resources (memory, most notably), you'll be fine without them. For example, a class with a single string or vector constituent doesn't really need them - unless you need some special copying behavior (the default will just copy over the members).

Instead of saying, "not all classes need them," wouldn't it be more accurate to say "retaining the default copy constructor, destructor and assignment operator will be fine."? (That is, you won't need to override the defaults with your own implementations.)

Under what circumstances must I provide, assignment operator, copy con...

c++ destructor copy-constructor assignment-operator
Rectangle 27 1

You will have to redefine all constructors that are not default or copy constructors. You do not need to redefine the copy constructor nor assignment operator as those provided by the compiler (according to the standard) will call all the base's versions:

struct base
{
   base() { std::cout << "base()" << std::endl; }
   base( base const & ) { std::cout << "base(base const &)" << std::endl; }
   base& operator=( base const & ) { std::cout << "base::=" << std::endl; }
};
struct derived : public base
{
   // compiler will generate:
   // derived() : base() {}
   // derived( derived const & d ) : base( d ) {}
   // derived& operator=( derived const & rhs ) {
   //    base::operator=( rhs );
   //    return *this;
   // }
};
int main()
{
   derived d1;      // will printout base()
   derived d2 = d1; // will printout base(base const &)
   d2 = d1;         // will printout base::=
}

Note that, as sbi noted, if you define any constructor the compiler will not generate the default constructor for you and that includes the copy constructor.

Note that the compiler won't provide a default ctor if any other ctor (this includes the copy ctor) is defined. So if you want derived to have a default ctor, you'll need to explicitly define one.

inheritance - How to use base class's constructors and assignment oper...

c++ inheritance constructor assignment-operator
Rectangle 27 1

class B
{
public:
    B(const B& b){(*this) = b;} // copy constructor in function of the copy assignment
    B& operator= (const B& b); // copy assignment
 private:
// private member variables and functions
};

In general, you can not define the copy constructor in terms of the copy assignment, because the copy assignment must release the resources and the copy constructor don't !!!

class B
{
public:
    B(Other& ot) : ot_p(new Other(ot)) {}
    B(const B& b) {ot_p = new  Other(*b.ot_p);}
    B& operator= (const B& b);
private:
    Other* ot_p;
};

To avoid memory leak , the copy assignment first MUST delete the memory pointed by ot_p:

B::B& operator= (const B& b)
{
    delete(ot_p); // <-- This line is the difference between copy constructor and assignment.
    ot_p = new  Other(*b.ot_p);
}
void f(Other& ot, B& b)
{
    B b1(ot); // Here b1 is constructed requesting memory with  new
    b1 = b; // The internal memory used in b1.op_t MUST be deleted first !!!
}

So, copy constructor and copy assignment are different because the former construct and object into an initialized memory and, the later, MUST first release the existing memory before constructing the new object.

If you do what is originally suggested in this article:

B(const B& b){(*this) = b;} // copy constructor

inheritance - How to use base class's constructors and assignment oper...

c++ inheritance constructor assignment-operator
Rectangle 27 4

The default copy constructor will copy the vector if it is declared by value. Beware if you stored pointers in your vector, in such a case, you need to provide specific behaviour for copy/assignement/destruction to avoid memory leaks or multiple delete.

Under what circumstances must I provide, assignment operator, copy con...

c++ destructor copy-constructor assignment-operator
Rectangle 27 4

Thanks - Updated with example

Sign up for our newsletter and get our top new questions delivered to your inbox (see an example).

c++ - Copy constructor and assignment operator implementation choices ...

c++ inheritance constructor assignment-operator deep-copy
Rectangle 27 6

As the name indicates, use unique_ptr when there must exist exactly one owner to a resource. The copy constructor of unique_ptr is disabled, which means it is impossible for two instances of it to exist. However, it is movable... Which is fine, since that allows transfer of ownership.

Also as the name indicates, shared_ptr represents shared ownership of a resource. However, there is also another difference between the two smart pointers: The Deleter of a unique_ptr is part of its type signature, but it is not part of the type signature of shared_ptr. That is because shared_ptr uses "type erasure" to "erase the type" of the deleter. Also note that shared_ptr can also be moved to transfer ownership (like unique_ptr.)

Although shared_ptr can be copied, you may want to move them anyways when you are making a transfer of ownership (as opposed to creating a new reference). You're obligated to use move semantics for unique_ptr, since ownership must be unique.

In the case of smart pointers, you should use copying to increase the reference count of shared_ptrs. (If you're unfamiliar with the concept of a reference count, research reference counted garbage collection.)

Yes. As mentioned above, shared_ptr can be both copied and moved. Copying denotes incrementing the reference count, while moving only indicates a transfer of ownership (the reference count stays the same.)

When you want to make a member-by-member copy of an object.

Concise, answers all the points. Have an upvote.

C++ Move Semantics vs Copy Constructor and Assignment Operator in rela...

c++ pointers c++11 smart-pointers move-semantics
Rectangle 27 3

1 - Should you have try-catch around the areas where we allocate the new memory for a deep copy in the copy constructor ?

In general, you should only catch an exception if you can handle it. If you have a way of dealing with an out-of-memory condition locally, then catch it; otherwise, let it go.

You should certainly not return normally from a constructor if construction has failed - that would leave the caller with an invalid object, and no way to know that it's invalid.

2 - With regards to inheritance for both the copy constructor and assignment operator, when should the base class functions be called, and when should these functions be virtual?

A constructor can't be virtual, since virtual functions can only be dispatched by an object, and there is no object before you create it. Usually, you wouldn't make assignment operators virtual either; copyable and assignable classes are usually treated as non-polymorphic "value" types.

Usually, you'd call the base class copy constructor from the initialiser list:

Derived(Derived const & other) : Base(other), <derived members> {}

and if you're using the copy-and-swap idiom, then your assignment operator wouldn't need to worry about the base class; that would be handled by the swap:

void swap(Derived & a, Derived & b) {
    using namespace std;
    swap(static_cast<Base&>(a), static_cast<Base&>(b));
    // and swap the derived class members too
}
Derived & Derived::operator=(Derived other) {
    swap(*this, other);
    return *this;
}

3 - Is std::copy the best way for duplicating memory in the copy constructor? I have seen it with memcopy, and seen others say memcopy the worst thing on earth.

It's rather unusual to be dealing with raw memory; usually your class contains objects, and often objects can't be correctly copied by simply copying their memory. You copy objects using their copy constructors or assignment operators, and std::copy will use the assignment operator to copy an array of objects (or, more generally, a sequence of objects).

If you really want, you could use memcpy to copy POD (plain old data) objects and arrays; but std::copy is less error-prone (since you don't need to provide the object size), less fragile (since it won't break if you change the objects to be non-POD) and potentially faster (since the object size and alignment are known at compile time).

Thanks - I updated the question with an example and some further discussion, Please take a look

@MikeyG: That's rather a lot of questions; you'd be better off asking them separately. Briefly: (4) you don't need to handle self-assignment if you're using copy-and-swap; (5) std::copy (and in general functions taking iterator ranges) expect the "end" iterator to be past the end of the sequence; (6) members are always initialised in the order they're declared in the class definition, so Data is initialised before size.

c++ - Copy constructor and assignment operator implementation choices ...

c++ inheritance constructor assignment-operator deep-copy
Rectangle 27 153

  • In C++11, in addition to copy constructors, objects can have move constructors. (And in addition to copy assignment operators, they have move assignment operators.)
  • The move constructor is used instead of the copy constructor, if the object has type "rvalue-reference" (Type &&).
  • std::move() is a cast that produces an rvalue-reference to an object, to enable moving from it.

It's a new C++ way to avoid copies. For example, using a move constructor, a std::vector could just copy its internal pointer to data to the new object, leaving the moved object in an incorrect state, avoiding to copy all data. This would be C++-valid.

Move-semantics require the moved object remain valid, which is not an incorrect state. (Rationale: It still has to destruct, make it work.)

@GMan: well, it has to be in a state that is safe to destruct, but, AFAIK, it does not have to be usable for anything else.

@ZanLynx: Right. Note that the standard library additionally requires moved objects be assignable, but this is only for objects used in the stdlib, not a general requirement.

It would swap its pointer, not copy it, I guess.

-1 "std::move() is the C++11 way to use move semantics" Please fix that. std::move() is not the way to use move semantics, move semantics are performed transparently to the programmer. move its only a cast to pass a value from one point to another where the original lvalue will no longer be used.

c++ - What is std::move(), and when should it be used? - Stack Overflo...

c++ c++11 move-semantics
Rectangle 27 5

I presume by this you mean, "When should I give my class a move constructor?" The answer is whenever moving objects of this type is useful and the default move constructor doesn't do the job correctly. Moving is useful when there is some benefit to transferring resources from one object to another. For example, moving is useful to std::string because it allows objects to be copied from temporaries without having to reallocate and copy their internal resources and instead by simply moving the resource from one to the other. Many types would benefit from this. On the other hand, moving is useful to std::unique_ptr because it is the only way to pass a std::unique_ptr around by value without violating its "unique ownership".

Again, I presume by this you mean, "When should I give my class a copy constructor?" Whenever you need to be able to make copies of an object, where internal resources are copied between them, and the default copy constructor doesn't do the job correctly. Copying is useful for almost any type, except those like std::unique_ptr that must enforce unique ownership over an internal resource.

Your classes should provide both copy and move semantics most of the time. The most common classes should be both copyable and moveable. Being copyable provides the standard semantics of passing around an object by value. Being moveable allows the optimisation that can be gained when passing around a temporary object by value. Whether this means having to provide a copy or move constructor depends on whether the default constructors do the appropriate things.

Should I ever use none and rely on the default copy constructor and assignment operator?

The default copy and move constructors just do a copy or move of each member of the class respectively. If this behaviour is appropriate for copying and moving your class, that's great. Most of the time, this should be good enough. For example, if I have a class that contains a std::string, the default copy constructor will copy the string over, and the default move constructor will move the string's resources to the new object - both do the appropriate job. If your class contains a std::unique_ptr, copying will simply not work, and your class will only be moveable. That may be what you want, or you may want to implement a copy constructor that performs a deep copy of the resource. The most important case in which you should implement copy/move constructors is when your class performs resource management itself (using new and delete, for example). If that's the case, the default constructors will almost never be doing a good job of managing those resources.

C++ Move Semantics vs Copy Constructor and Assignment Operator in rela...

c++ pointers c++11 smart-pointers move-semantics
Rectangle 27 3

Q0. No, this calls the copy constructor only. That's a pretty big misunderstanding, objects are only ever constructed once.

Q2. Presumably you are meant to store the array size in size. E.g.

IntPart::IntPart()
{
    Counts = new int[101] (); // allocate all to 0s
    numParts = 0;
    size = 101; // save array size
}

Q3. I would look up the copy and swap idiom. This lets you write the assignment operator using the copy constructor.

c++ - Rule of Three. Copy Constructor, Assignment Operator Implementat...

c++ destructor copy-constructor assignment-operator rule-of-three
Rectangle 27 2

No but there are a number of reasons why you shouldn't allow the compiler to auto generate these functions.

In my experience it is always best to define them yourself, and to get into the habit of making sure that they are maintained when you change the class. Firstly you may well want to put a breakpoint on when a particular ctor or dtor is called. Also not defining them can result in code bloat as the compiler will generate inline calls to member ctor and dtor (Scott Meyers has a section on this).

Also you sometimes want to disallow the default copy ctors and assignments. For example I have an application that stores and manipulates very large blocks of data. We routinely have the equivalent of an STL vector holding millions of 3D points and it would be a disaster if we allowed those containers to be copy constructed. So the ctor and assignment operators are declared private and not defined. That way if anyone writes

class myClass {
  void doSomething(const bigDataContainer data); // not should be passed by reference
}

then they'll get a compiler error. Our experience is that an explicit become() or clone() method is far less error prone.

So all in all there are many reason to avoid auto generated compiler functions.

not
note

"get into the habit of making sure that they are maintained when you change the class". That's an unnecessary maintenance nightmare.

Should you not have unit tests for your ctors etc to check for correct initialisation? Should you not be considering all the implications of adding data members to classes? If you add a new string to a class what is the impact on code bloat across all the methods that use it, and across all the classes that may contain instances of it? Having added a new member do you not have to reconsider whether allowing autogeneration is viable any more? Whilst you are wondering about all those things adding to the copy-ctor and op= is minimal.

So you'll also need to keep unit tests updated? (It really hasn't occurred to me that I should test assignment of simple classes containing a couple of strings.) - May-be there's something in the code bloat, but in such case, doesn't "optimize for size" options help?

Under what circumstances must I provide, assignment operator, copy con...

c++ destructor copy-constructor assignment-operator
Rectangle 27 2

I can think of a few cases when you need to write your own Big Three. All standard containers know how to copy and destroy themselves, so you don't necessarily need to write them. Here's how to know when you do:

The default copy semantics for pointers is to copy the value of the pointer, not what it points to. If you need to deep copy something, even if it's stored inside a standard container, you need to write your own copy constructor and assignment operator. You also need to write your own destructor to properly free those resources.

Base classes need a destructor. Herb Sutter recommends making them either public and virtual (most common case) or protected and non-virtual, depending on what you want to do with them. The compiler-generated destructor is public and non-virtual, so you'll have to write your own, even if it doesn't have any code in it. (Note: this doesn't imply you have to write a copy constructor or assignment operator.)

Should I prevent a user from copying objects of my class?

If you don't want the user to copy your objects (maybe that's too expensive), you need to declare the copy constructor and assignment operators either protected or private. You don't have to implement them unless you need them. (Note: this doesn't imply you have to write a destructor.)

The most important thing is to understand what the compiler-generated copy constructor, assignment operator, and destructor will do. You don't need to be afraid of them, but you need to think about them and decide if their behavior is appropriate for your class.

Under what circumstances must I provide, assignment operator, copy con...

c++ destructor copy-constructor assignment-operator
Rectangle 27 1

tempCat = tempCat3

is investigated by overload resolution and rewritten as

tempCat.operator=(tempCat3)
CCat& operator=( CCat oldCat )

The parameter oldCat has to be initialized with the argument, tempCat3. The correct term is actually copy-initialization.

The initialization that occurs in the form

T x = b;

copy-initialization only works with non-explicit constructors:

For copy-initialization, the candidate functions are all the converting constructors (12.3.1) of that class.

A constructor declared without the function-specifier explicit specifies a conversion from the types of its parameters to the type of its class. Such a constructor is called a converting constructor.

So if you declare your copy constructor with the const-reference parameter as explicit, it isn't a converting constructor, copy-initialization doesn't work and the parameter cannot be initialized with the argument - that is also what the compiler tells us, no matching constructor was found. The same applies to the other lines in main.

If explicit is removed the initialization works just fine.

You have definately increased my knowledge today. Where can I look to get further general info on the steps the compiler takes when passing source code, eg. as you have explained above? Also I don't understand why "copy-initialization only works with non-explicit constructors" am I missing something?

c++ - assignment operator by value not compiling with explicit copy co...

c++ copy-constructor assignment-operator
Rectangle 27 1

When you don't pass the argument by reference in the copy-assignment operator, then the compiler copies the argument you pass, and the function uses that copy. That the function called is the copy-assignment operator doesn't matter, it's the same for all functions.

Search and read more about pass-by-value and pass-by-reference.

As for the return value, the same thing happens there: The compiler creates a copy of the returned value. If you had properly implemented your copy-constructor to actually copy something, the result would have been different.

c++ - Class assignment operator and copy constructor - Stack Overflow

c++
Rectangle 27 2

The issue has nothing to do with copy constructor, and you didn't call it at all. The point is the two t(io)s are not the same thing.

t(io) in member initialization list means construct t by the constructor taking io as its argument. (I suppose boost::asio::deadline_timer has a constructor taking boost::asio::io_service as parameter.)

t(io) in the body of constructor is a statement, means calling t as a functor, passing io as its argument. It fails because boost::asio::deadline_timer doesn't support such functor behavior.

c++ - Member initialization list vs assignment/copy constructor (in bo...

c++ boost member-initialization
Rectangle 27 1

those container will need a "copy constructible" element, and if you don't supply the copy constructor, it will call default copy constructor of your class by deducing from your class members (shallow copy).

it is so with destructor, the container need to have access to your destructor or your default class destructor if you don't provides one (ie. it will not work if you declare your destructor as private )

Found the information at the supplied link very helpful.

Under what circumstances must I provide, assignment operator, copy con...

c++ destructor copy-constructor assignment-operator