is that correct to write a constructor like this?
class A
{
A(const A& a)
{
....
}
};
if yes, then is it correct to invoke it like this:
A* other;
...
A* instance = new A(*(other));
if not, what do you suggest?
Thanks
Almost correct. When declaring the constructor in the class, simply write A, not A::A; you would use A::A when giving a definition for the constructor outside of the class declaration. Otherwise, yes.
Also, as James points out, unless you are copying from an object that you are accessing via a pointer, you don't need to do any dereferencing (if it is a value or a reference). One typically does not use pointers unless it is necessary to do so. On that principle, you would have something like:
A x; // Invoke default constructor
// ...
// do some thing that modify x's state
// ...
A cpy(x); // Invokes copy constructor
// cpy now is a copy of x.
Note, though, that the first statement A x invokes the default constructor. C++ will provide a default implementation of that constructor, but it might not be what you want and even if it is what you want, it is better style, IMHO, to give one explicitly to let other programmers know that you've thought about it.
Edit
C++ will automatically provide an implementation of the default constructor, but only if you don't provide any user-defined constructors -- once you provide a constructor of your own, the compiler won't automatically generate the default constructor. Truth be told, I forgot about this as I've been in the habit of giving all constructor definitions myself, even when they aren't strictly necessary. In C++0x, it will be possible to use = default, which will provide the simplicity of using the compiler-generated constructor while at the same time making the intention to use it clear to other developers.
No, you are writing a copy constructor. It will not act as you expect (according to the examples provided).
class A{
A(arguments){ ...}
}
I would suggest reading a C++ book, differences between a constructor and a copy constructor are well explained.
When is it used ? When an instance is copied. For example, by returning /passing an instance by value
void foo (A a){
//copy constructor will be called to create a
}
A bar(){
return a; //Copy constructor will be called
}
Related
I often find myself using unique pointers in C++ when I want polymorphic behaviour. I typically implement pure abstract classes something like the below:
class A {
public:
virtual A* clone() const = 0; // returns a pointer to a deep copy of A
// other methods go here
};
The clone method comes in handy when I want to embellish another class with its own instance of A, for example:
#include <memory>
class B {
private:
std::unique_ptr<A> a_ptr;
public:
// ctor
B(const A& a) {
a_ptr = std::unique_ptr<A>(a.clone());
//...
}
// copy ctor
B(const B& other) : B(*other.a_ptr) {}
};
I invariably end up implementing the copy constructor in B to avoid a compiler error (MSVC gives a vague message about attempting to reference a deleted function), which makes complete sense because of the unique pointer. My questions can be summarised as follows:
Do I actually need the copy constructor in B? Perhaps there's a better pattern that would allow me to avoid it altogether.
If yes to 1, can I stop there? Will I ever need to implement the other default functions? I.e. is there any scenario where I need a default constructor and destructor also?
In practice, whenever I feel I need to implement the default functions, I typically implement a move-constructor alongside the other three; I usually use the copy-and-swap-idiom (as per GManNickG's answer in this thread). I assume this wouldn't change anything, but maybe I am wrong!
Thanks a lot!
First, I think the signature of your clone function could be
virtual std::unique_ptr<A> clone() = 0;
as you want deep copies of A instances and exclusive ownership within B. Second, you indeed have to define a copy constructor for your class when you want it to be copyable. Same for an assignment operator. This is due to the fact that std::unique_ptr is a move-only type, which hinders the compiler to generate default implementations.
Other special member functions are not needed, though they might make sense. The compiler won't generate move constructor and move assignment operator for you (as you ship your own copy/assignment functions), though in your case, you can = default; them easily. The destructor can equally well be defined with = default;, which would be in line with the core guidelines.
Note that defining the destructor via = default should be done in a translation unit, as std::unique_ptr requires the full type do be known upon freeing its resource.
Whether you need a default constructor totally depends on how yo want to use the class B.
As #lubgr mentioned in his answer, You should return unique_ptr not a raw one from the clone function. Anyway, going to Your questions:
Do You need a copy constructor in B? Well it depends on Your use cases, but if You copy objects of class B You may need one. But as You said, You do it quite often, so it would be wise to consider more generic approach. One of these would be creating a wrapper for unique_ptr which would have copy constructor and which would make a deep copy of this pointer in this copy constructor.
Consider following example:
template<class T>
class unique_ptr_wrap {
public:
unique_ptr_wrap(std::unique_ptr< T > _ptr) : m_ptr(std::move(_ptr)){}
unique_ptr_wrap(const unique_ptr_wrap &_wrap){
m_ptr = _wrap->clone();
}
unique_ptr_wrap(unique_ptr_wrap &&_wrap){
m_ptr = std::move(_wrap.m_ptr);
}
T *operator->() const {
return m_ptr.get();
}
T &operator*() const {
return *m_ptr;
}
private:
std::unique_ptr< T > m_ptr;
};
This again depends on Your needs. I personally would recommend overloading move constructor as well, to make it use less dynamic allocations (but this may be premateure optimization which is root of all evil).
I am new to object oriented programming, and this may be a silly question, but I don't understand why is using class A code better to use than class B if you want to create copy of one object.
class A {
int num;
public:
A(const A &ref) : num(ref.num) {};
};
class B {
int num;
public:
B(B *ptToClass) : num(ptToClass->num) {};
};
If I got this right, copy constructor is used in class A.
If you don't declare a copy constructor for your class, the compiler will declare one for you anyway. Classes have to have copy constructors. They're baked into the language and have special status. The language doesn't work without them.
Possibly the best example is that copy constructors are needed when passing by value. The compiler is going to implicitly call the copy constructor when you pass by value. It's not going to call the constructor B::B(B*).
So if you want your class to be copyable, you should define the copying logic in the copy constructor. It's just easier.
Class A is flexible and safe: you create a copy from any A object you have, even if it's a temporary one.
Class B is less safe as you could invoke the constructor with a nullptr. It's less flexible because you can only use ypur constructor to copy an object from which you can get the address and which is not const.
B b1(...);
const B b2(...);
B fb(); // function returning a B
B b3(&b1);
B b4(&b2); // error b2 is const
B b5(&fb()); // error you can't take adress of a temporary
The thing is that if a constructor is considered to be a copy constructor by the compiler, it is used in special ways. For instance, if you have a function that takes a parameter of your type A by copy, like this:
void function(A obj) {
// Do something with A
// ...
}
And then you call that function:
int main() {
A a_obj;
function(a_obj);
}
the object obj received by function will be created by the copy constructor you provided. So, it is a nice thing to provide copy constructor for your classes that are meant to be copied, so that them fits more nicely with the languages features and libraries.
There is no problem in creating a constructor of the kind in your class B, if that fit your needs in your application, but that will not be understood by the compiler as a copy constructor, and won't be used when the compiler or libraries needs to copy your objects.
It is forbidden by standard to use pointers in copy constructors:
C++ draft standard n3376 - section 12.8.2:
A non-template constructor for class X is a copy constructor if its
first parameter is of type X&, const X&, volatile X& or const volatile
X&, and either there are no other parameters or else all other
parameters have default arguments
Why is the argument of the copy constructor a reference rather than a pointer?
I think a more appropriate question to ask is: when to provide a user-defined copy constructor over the default one provided by the compiler?
As we know, the compiler provides a copy constructor (the default one) which does a memberwise copy.
This memberwise copy is not bad as long as the class is a simple concrete type (that behaves for the most part like a built-in type). But for complex concrete types or classes with hierarchies, memberwise copy is not a good idea, and the programmer is highly advised to provide his own implementation of the copy constructor (that is, provide user-defined copy constructor).
As a thumb rule, it is a good idea to provide user-defined copy constructor in the class.
In a small game I'm writing, I have a class Weapon with two constructors, one which takes in some parameters to produce a custom weapon, and one that grabs a default one (the CHAIN_GUN):
Weapon::Weapon (void) {
// Standard weapon
*this = getWeapon(CHAIN_GUN);
return;
}
Question: Are there any negative consequences from using *this and operator= to initialise a class?
Imagine that someone asked you to draw a painting... would you;
first draw your default (1st) (that familiar smilie face you like so much),
then draw what that someone asked for (2nd),
only to draw the same thing one more time, but on the canvas containing your default,
and then burn the 2nd painting?
This post will try to explain why this simile is relevant.
WHY IS IT A BAD IDEA?
I've never seen a default-constructor implemented with the use of the assignment-operator, and honestly it's not something that I'd recommend, nor support during a code review.
The major problem with such code is that we are, by definition, constructing two objects (instead of one) and calling a member-function, meaning that we construct all our members two times, and later having to copy/move initialize all members by calling the assignment operator.
It's unintuitive that upon requesting construction of 1 object, we construct 2 objects, only to later copy the values from the 2nd to the 1st and discard the 2nd.
Conclusion: Don't do it.
( Note: In a case where Weapon has base-classes it will be even worse )
( Note: Another potential danger is that the factory function accidentially uses the default-constructor, resulting in an infinite recursion not caught during compilation, as noted by #Ratchet Freat )
PROPOSED SOLUTION
In your specific case you are far better off using a default-argument in your constructor, as in the below example.
class Weapon {
public:
Weapon(WeaponType w_type = CHAIN_GUN);
...
}
Weapon w1; // w_type = CHAIN_GUN
Weapon w2 (KNOWLEDGE); // the most powerful weapon
( Note: An alternative to the above would be to use a delegating constructor, available in C++11 )
Using the assignment operator to implement a constructor is rarely a good idea. In your case, for example, you could just use a default parameter:
Weapon::Weapon(GunType g = CHAIN_GUN)
: // Initialize members based on g
{
}
In other cases, you might use a delegating constructor (with C++11 or later):
Weapon::Weapon(GunType g)
: // Initialize members based on g
{
}
Weapon::Weapon()
: Weapon(CHAIN_GUN) // Delegate to other constructor
{
}
One thing to keep in mind is that if operator= - or any function it calls - is virtual, the derived-class version won't be invoked. This could result in uninitialised fields and later Undefined Behaviour, but it all depends on your data members.
More generally, your bases and data members are guaranteed to have been initialised if they have constructors or appear in the initialiser list (or with C++11 are assigned to in the class declaration) - so apart from the virtual issue above, operator= will often work without Undefined Behaviour.
If a base or member has been initialised before operator=() is invoked, then the initial value is overwritten before it's used anyway, the optimiser may or may not be able to remove the first initialisation. For example:
std::string s_;
Q* p_;
int i_;
X(const X& rhs)
: p_(nullptr) // have to initialise as operator= will delete
{
// s_ is default initialised then assigned - optimiser may help
// i_ not initialised but if operator= sets without reading, all's good
*this = rhs;
}
As you can see, it's a bit error prone, and even if you get it right someone coming along later to update operator= might not check for a constructor (ab)using it....
You could end up with infinite recursion leading to stack overflow if getWeapon() uses the Prototype or Flyweight Patterns and tries to copy-construct the Weapon it returns.
Taking a step back, there's the question of why getWeapon(CHAIN_GUN); exists in that form. If we need a function that creates a weapon based on a weapon type, on the face of it a Weapon(Weapon_Type); constructor seems a reasonable option. That said, there are rare but plentiful edge cases where getWeapon might return something other than a Weapon object that can never-the-less be assigned to a Weapon, or might be kept separate for build/deployment reasons....
If you have defined a non-copy = assignment operator that lets the Weapon change its type after construction, then implementing the constructor in terms of assignment works just fine, and is a good way to centralize your initialization code. But if a Weapon is not meant to change type after construction, then a non-copy = assignment operator does not make much sense to have, let alone use for initialization.
I'm sure yes.
You already created object inside your "getWeapon" function, and then you copying it, that may be long operation. So, at least you have to try move semantic.
But.
If inside "getWeapon" you call to constructor (and you do, somehow "getWeapon" have to create your class to return it to your copy operation), you create very unclear architecture, when one constructor calls function that calls another constructor.
I believe you have to separate your parameters initialization to private functions, that have to be called from your constructors the way you want to.
class Foo {
public:
Foo() { Foo(1)}
Foo(int x, int y = 0):i(x) {}
private:
int i;
}
Can anybody give me some reasonas about can I do this? If not why?
Because the language specification doesn't allow it. Just the way the language is. Very annoying if you're used to Java or other languages that allow it. However, you get used to it after a while. All languages have their quirks, this is just one of C++'s. I'm sure the writers of the specs have their reasons.
Best way around this I've found is to make a common initialization function and have both constructors call that.
Something like this:
class Foo {
public:
Foo() {initialize(1);}
Foo(int nX) { initialize(nx); }
private:
void initialize(int nx) { x=nx; }
int x;
};
It's a language design choice.
A constructor is a one time (per-object) operation that creates a new object in uninitialized memory. Only one constructor can be called for an object, once it has completed the object's lifetime begins and no other constructor can be called or resumed on that object.
At the other end of its life a destructor can only (validly) be called once per object and as soon as the destructor is entered the object's lifetime is over.
A prinicipal reason for this is to make explicit when an object destructor will be run and what state it can expect the object to be in.
If a class constructor completes successfully then it's destructor will be called, otherwise the object's lifetime has never begun and the destructor will not be called. This guarantee can be important when an object acquires resources in its constructor that need to be released in its destructor. If the resource acquisition fails then the constructor will usually be made to fail; if the destructor ran anyway it might attempt to release an resource that had never been successfully acquired.
If you allow constructors to call each other it may not be clear if a calling or a called constructor is responsible for the resource. For example, if the calling constructor fails after the called constructor returns, should the destructor run? The called constructor may have acquired something that needs releasing or perhaps that was what caused the calling construtor to fail and the destructor shouldn't be called because the resource handle was never valid.
For simplicity of the destruction rules it is simpler if each object is created by a single constructor and - if created successfully - destroyed by a single destructor.
Note that in C++11 a constructor will be able delegate to a different constructor, but there are limitations that don't really relax the principal of one construction per object. (The prinicipal constructor can forward to a target constructor, but if it does it must not name anything else (base classes or members) in its initializer list. These will be initialized by the target constructor, once the target constructor returns the body of the prinicipal constructor will complete (further initialization). It is not possible to re-construct any bases or members, although it allows you to share constructor code between constuctors.)
You cant do this. See section 10.3: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.3. You can try to do it but doing so will construct a new temp object (not this) and be destroyed once control moves on.
What you can do however is to create a private function that initializes variables, one that your default constructor or a parameterized constructor can both call.
There is a really hideous hack I have seen used to call another ctor. It uses the placement new operation on the this pointer. erk
Like this:
Class::Class(int x) : x_(x) {}
Class::Class() {
new (this) Class(0);
}
Class::Class(const Class &other) : x_(other.x_) {}
Class& operator=(const Class &other) {
new (this) Class(other);
return *this;
}
Note that I am not recommending this, and I don't know what horrible effects it might have on C++ structures like virtual base classes, etc. But I expect that there are some.
Although as per standards vendors are free to implement data binding in their own ways, if we consider the most popular implementation: this pointer, we can see a reason why this can't be implemented.
Assume you have a class:
class A
{
public:
A(){}
A(int a){}
} ;
With the this pointer implementation, this class would look something like:
class A
{
public:
A(A *this){}
A(A *this,int a){}
} ;
Typically you would create objects like this:
A ob ;
Now when compiler sees this, it allocates memory for this and passes the address of this allocated memory block to the constructor of A which then constructs the object. It would try to do the same every time for each constructor called.
Now when you try calling a constructor within another constructor, instead of allocating new memory the compiler should pass the current objects this. Hence inconsistency!
Then another reason which i see is that even though you might want to call a constructor within another, u would still want a constructor to call default constructors for all the objects within the class. Now if one constructor were to call another, the default construction should happen for the first constructor and not for the subsequent one's. Implementing this behavior means that there would be several permutations which need to be handled. If not, then degraded performance as each constructor would default construct all the objects enclosed.
This is what i can think of as possible reasons for this behavior and do not have any standards to support.
In writing a copy constructor for one of my classes ( which holds a few objects of other UDTs ), I am required to create a default constructor for those UDTs, even though they were never really meant to have one.
Is it fine to just implement a blank default constructor and be done with it? The only time the default constructor is invoked is during this copying, when the object is created and then the values of the corresponding object are copied to it. Thus, whatever values are assigned to the object in the default constructor will never actually be used.
The problem I see is that some member variables aren't initialized in a blank default constructor. Should I just write one that gives dummy values instead? Any other recommended ways to handle this?
Edit: I understand that a copy constructor doesn't NEED a default constructor if I were to define copy constructors for the other classes, but I didn't, so it does need it.
If you use an initializer list in the copy constructor, you don't need a default constructor:
#include <iostream>
using namespace std;
class Foo {
Foo(); /* no default constructor */
public:
Foo(int i) { cout << "Foo constructor (int)" << endl; }
Foo(const Foo& f) { cout << "Foo constructor (copy)" << endl; }
};
class Bar {
Foo f;
public:
Bar() : f(1) { cout << "Bar constructor (default)" << endl; }
Bar(const Bar& b) : f(b.f) { cout << "Bar constructor (copy)" << endl; }
};
int main(void) {
Bar b;
Bar b_=b;
return 0;
}
Results in:
Foo constructor (int)
Bar constructor (default)
Foo constructor (copy)
Bar constructor (copy)
Are you actually sure you need a copy constructor? It's unusual (but not impossible) to have a class where the default constructor would be OK, but you need a custom copy constructor. Perhaps you could post the code for your class?
It sounds to me like you need to define copy c'tors for the other classes, as you are creating objects of them by copying other objects.
You say:
when the object is created and then
the values of the corresponding object
are copied to it.
But ask yourself - how do the values of that "corresponding object" get there in the first place. I.e. how was the corresponding object created?
This previous SO discussion may help clarify matters for you.
This doesn't sound like the best way to implement a copy constructor. If the contained types provide copy constructors themselves - use those. There might be a reason a type does not provide a default constructor after all.
I would first ask why copying those UDTs involves the default constructor, rather than the more appropriate copy constructor. I would also ask what it means for an object to be in the default initialized state — if it does mean something, then by all means implement it.
If you have no reasonable meaning for a default initialization, and you absolutely have to define the object using a default constructor, I suppose implementing a default constructor could be afforded.
However, not all objects can get a default constructor, so fixing the source of the problem is still a good idea.
You can prevent the default constructor by requiring the other object to have copy constructors also (Or use special constructor which pass in all information needed to construct the objects. Generally having default constructor which don't initialize all member variables is a very bad idea. At a minimum make sure the default constructors of the other class initializes all members.
If you don't want the compiler to generate a copy constructor or don't want a copy constructor at all, then declare a private copy constructor but don't provide any definition (code) for it. The compiler will see the declarations and not generate one. Also do this with the assignment operator.
I do this with my singleton classes.
If your class isnt meant to be defaultly constructed, don't create a default constructor.
If it is, then I'm sure you can figure out a sensible initialization, so that's what you should be using.
Remember a thumb rule that as far as something is not part of specification , compiler won't do it for you.
If your class contain user defined type and when you create object of it , then compiler has to call default constuctor for each object.
But to initialize data members of object is not complier's task, but you are suppose to do it.
For the case you have mentioned , you need your own custom copy constructor and assignment operator.
The question, the way you stated it, appears to make no sense. Copy-constructor does not need the default constructor, as you seem to believe. Copy-constructor is a completely independent full-fledged constructor that construct an object completely by itself.
If you construct your objects with copy-constructor, then you don't need a default one. If you construct your objects with default constructor, then you can't use the copy-constructor on them. It is not possible to "apply" two different constructors to the same object.
If you construct your objects in both ways, then they become two completely independent constructors, each having its own independent purpose. In this case the question you should be asking yourself is how you want your objects to be defualt-constructed. Only you know that.
Again, you need to clarify your question. I would suspect (from your description) that maybe what you are trying to implement is not copy-constructor, but a copy-assignment operator. But that's just a wild guess.