You have to explicitly list all of the members that you want copied in a copy constructor, this means that you could set up a copy constructor to copy cut down versions of your object.
but how does the member function copying work? are all member functions automatically included? Is this because an object is really just the members and the functions just declare how a class can be used? Does this mean you could in theory create cut down objects with a copy constructor and then, for example, call a getter to get a member that doesn't exist in your copy?
Member functions are not stored in class instances. They're just regular functions. A vtable pointer can be stored however. It is used for dynamic dispatch of virtual member functions.
Normal member function calls are determined at compile time.
(as a side-note, there are some languages that do store copies of methods per-instance, although C++ isn't one of them)
Functions don't have a separate instance for each instance; the characteristic of a (non-static) member function isn't that it will be instantiated for each instance, but that it must be called on an instance, and will implicitly receive a pointer to the instance. There's no copying of functions. (In fact, functions—member or otherwise—can't be copied.)
There is probably a misunderstanding about what classes/objects are in C++. In some languges (e.g. python), objects can change (new variables/functions); in C++, objects are static, as specified in the class, so there can not be shrinked down version of your object.
The default copy constructor already does a member to member copy. If this is not enough (shallow copy <-> deep copy), you have to provide your own version of the copy constructor in which you have to do all the copying. Failing to copy a member will leave the copied version with an undefined or default member. It is best to avoid having to make your own copy constructor by avoiding dynamic memory and the likes.
Related
How does defining prototypes for copy constructor in private section of class prevents copying of class in C++
In C++, member functions which are in the private section of a class can only be called by other member functions of the same class. (Similarly, protected members can be called by derived classes, and public members can be called by anyone.)
In order to copy an object, you need a copy constructor. If you don't write your own, then the compiler will supply one for you. But if you do write your own, then the usual access rules will apply. So if you put the definition of the copy constructor in the private section of your class, then the compiler will see that there is a constructor with the right signature (so it won't provide you with one), but then complain that it can't call it because it's private.
Back in the old C++98 days, this was the usual way to prevent copying of a class. C++11 has a better approach: you say
struct MyType
{
MyType(const MyType&) = delete;
};
to explicitly say to the compiler "I am not providing this function, and do not generate it function for me". This has the same effect as defining a private copy constructor, but provides a better error message to anyone attempting to copy the class.
Whenever you pass a non temporary object or an object with value it tries to use an accessible copy constructor to create object. Once its explicitly deletedC++11 or put in private/protected section, access from outside is not possible leading to an error at compile time, hence making you aware that copying is not possible.
Such class are not Copy-Construtible .
I am writing a class which uses the stl class map as a member. I have no pointers in the class. Do I need to write a custom copy constructor or will the default copy constructor work fine?
After reading the answers I am adding some more information. I have static const variables but those are not initialized during construction. I have no reference members. Everything else is a 64 bit integer. I also have a map iterator as a member in the class.
The default copy constructor will always work (it just calls the copy constructors of all the class members).
Generally speaking, the only time you may have an issue is when you are using members that carry non-trivial construction/destruction (like objects that manage a global resource such as file descriptors for files/kernel services and pointers for memory) that would be (and need to be) cleaned up by the destructor and reallocated by the copy constructor.
I know of some optimizations that can make the copy constructor faster if you implement it, but they aren't really necessary.
Pointer members aren't the only things that would cause problems here. There are several factors that may require you to have a custom copy constructor, including but not limited to:
Reference members, as they require explicit initialization
const member variables, same reason
Any member variables of types that do not provide copy constructors
There is a way in C++ to prohibit copy of an object of particular type. Well written libraries including STL only allow types to be copy constructable if it is safe and does make sense for that type. So if you can copy it (compiler does not generate errors), then it is safe. It is a good practice to follow this in your own program, even if it is not so big.
The default copy constructor will do fine.
Node*Clone(){
numClones++;
Node*cloned=new Node(*this);
return cloned;
}
I have a default constructor (taking no arguments) and I have no declared copy constructors, so I'd expect this to simply copy the entire contents of the memory of *this and return a pointer to it.
However, I am getting error on the new line above:
Call to implicitly deleted copy constructor
Two possible issues but I don't think they should affect this:
this has a unique_ptr attached to it. That is it contains a container of unique_ptr and is itself stored in another container of unique_ptr. But I am not moving that pointer, I am creating new object not attached to the prior object, right?
this is actually a subclass of Node but I want to return a pointer to a base class
As Jeffrey said, std::unique_ptr cannot be copy-constructed.
Also your Clone methods is not logically correct. Because you are instantiating a Node object there - a base class. So it will not be a copy actually
As a solution you may declare a Clone method in the base class and make in pure virtual:
class Node
{
virtual Node * Clone() const = 0;
}
And make your subclasses implement it
PS: don't forget about virtual or protected dtor in the interface
The error message "Call to implicitly deleted copy constructor" means that your class, one of its base classes and/or some of the data members of that class or any of its base classes are declared as non-copyable (or are treated as non-copyable by the compiler which may happen, for example, when at least one of data members is a reference). Therefore, compiler cannot come up with a "default" copy constructor that you are attempting to call with new Node(*this);
The proper way in such a case is to actually find what objects exactly are non-copyable and either make them copyable so that compiler could create an implicitly defined copy constructor, or implement your very own "copying logic" and not use a copy constructor.
Another alternative is to use some sort of a "smart" pointer pointer (i.e. std::shared_ptr). But in that case you get a shallow copy instead of a deep copy.
Since you are doing a copy of yourself, I would really suggest you implement a copy constructor. It's best practice to control, plus if you add memory points in the class, you will really mock things up..
Don't rely on this in your case, here is why not:
Conditions for automatic generation of default/copy/move ctor and copy/move assignment operator?
The problem is caused by your attempt to copy construct a std::unique_ptr (by copying a Node) which, by definition, does not have a copy constructor.
You probably meant to use std::shared_ptr.
I know that when you call a function this way :
foo(MyClass a)
The object a is being passed by value meaning it's being copied.
My question is how is it being copied?
say my class don't have a copy constructor, so if it is passed using shallow copy than
the object may change inside the function?
Compiler automatically generates the code for the copy constructor and performs member wise copy. The copy constructor which compiler calls does member wise copy which is indeed shallow copy.
It is inadvisable to pass an object by value if a pointer in your class exists. Even if a pointer does not exist, but a dozen other data members exist, they would require a lot of time to get copied.Pass it by reference, and make it const if you dont want its value to be changed.
There are two possibilities.
First: You didn't specify a copy constructor.
In this case the default copy constructor MyClass::MyClass(MyClass const&) will be used. This will attempt to copy construct all of MyClass's member (recursively, as these may have members themselves). If any of these members is not copy constructible your default copy constructor will therefore fail as well (see next point).
Second: You declared the copy constructor private or actually deleted it (in C++11).
In this case, you will not be able to pass anything to this function, because the compiler will require access to a copy constructor, which you denied it. This will lead to compile time errors.
the compiler creates a default copy constructor.
When is a class implicitly copied in C++?
I have a class that contains a unique_ptr, and therefore cannot be safely copied, and therefore, I disabled the copy constructor on the class by creating private versions of X(X&) and X& operator = X&.
I immediately ran into the problem that instances of this class cannot be returned, because returning actually makes a copy of the instance.
Are there any other situations I need to watch out for?
Returning does not copy the instance, it moves the instance. You just forgot to provide a move constructor. In addition, classes are now moved when used in Standard containers in most situations in which they used to be copied.
In short, provide a move constructor and move assignment operator (and swap, preferably) and you should find that almost all situations where copies are implicit, they're now moves.
The situations that come to mind are: functions that receives the class by value, functions that returns then class by value, and any class or container that contains that class. Classes like std::vector will use move semantics whenever possible (you did overload that right)? but will be unable to use functions that require a copy constructor, such as copying the vector. As GMan said though, you can make a copy constructor for your class, and do a deep copy of the std::unique_ptr manually, if you want to make things easier.