Could someone please explain what is meant by the following?
You must define a default constructor if your class defines member variables and has no other constructors. Otherwise the compiler will do it for you, badly.
What are they referring to as "badly"?
From the expansion of that link:
"The reason for this is that if you
have no other constructors and do not
define a default constructor, the
compiler will generate one for you.
This compiler generated constructor
may not initialize your object
sensibly."
Might refer to how new T and new T() differ when there is no ctor provided.
It's good to be sure that the object is created in a known state. Primitive variables won't be set to zero by default, so you could end up with subtle bugs that don't always show up. By initializing the member variables to sensible variables, everything is much more predictable.
The only problem with the default constructor is that it initializes only what the compiler thinks must be initialized, and not what you may think needs to be initialized. Basically, that means that it will invoke initializers for objects with default initializers. It won't set pointers or simple types like int to sane values, etc. If that is sufficient, then the default constructor is not 'bad'. When it is insufficient, it is a bug (in your code) that you did not define the necessary default constructor with the correct initialization.
Take the Google style guide with a grain of salt -- or maybe a truckload of salt.
It is true that the compiler-generated default constructor won't necessarily initialize members that are of built-in types in a meaningful fashion. If you want that done, then yes, its failure to do that is bad. OTOH, if you don't want that done, then its doing it could be somewhat bad (wasteful) as well.
Bottom line: there are times to write your own default ctor, but they tend toward the exception, not the rule. Although there are simple rules of thumb to cover a lot of cases in C++ and will prevent a lot of problems, this really isn't one of them -- here you pretty much do need to know what the compiler-generated ctor will do, and what you want different if you're going to write your own.
In Debug build most compilers fill uninitialized space with some magic values, so that debugging is reliable. And providing custom constructor prevents certain POD optimizations.
In fact, it's a guideline just to make sure people does explicitely make the statement of what is an invalid or default state of any object.
That way, no surprise when reading the code, compared to the actual execution.
However, think that it's a company guideline, that is used to make sure everyone does follow the same rules, that's not a you-must-follow-it-because-google-does-it.
In fact, if you manage to make all your member objects being in valid state when default constructed, or force you to set a constructor, then there is no good reason for such a guideline.
If you have any primitive types as member variables (eg. int, float), then the default ctor will not initialize them. member variables that are a class type will have their default ctor's invoked.
Prefer member initializer lists, so your user supplied ctor may be empty:
class Foo {
int bar;
float baz;
Foo(): bar(0), baz(0.0f) { /* empty ctor body */ }
};
It won't set integers to 0 or pointers to null. It will run default constructors on object of types with constructors.
Some people would call it 'not sensible'.
It just seems a too simplified version of the rules of 3, you should either define yourself or leave the compiler version of
the copy constructor
the assignment operator
the destructor
(Note that by defining yourself a copy constructor, the compiler won't define a default constructor).
The default constructor built by the compiler does 'nothing', it will not even zero the memory occupied by the object
Related
Why is it recommended that you explicitly declare a copy constructor,even when the compiler makes a public copy constructor when you use objects as parameters , use objects as a return value or even construct an object based on another of the same class?
Copy constructor is needed when object has dynamic memory allocations.
In default c++ compiler creates copy constructor, so when you do not have pointer etc. you do not need to define copy constructor.
Why is it recommended that you explicitly declare a copy constructor,even when the compiler makes a public copy constructor
It isn't.
If you don't have special logic to perform in a copy constructor, you don't need to provide one, and doing so is just noise.
If you do, then obviously you have to write that code by providing your own copy constructor.
Some older texts might propose you declare all special member functions, even if their definitions are empty, because if you want to add meaningful definitions later you then do not change the header that contains the definition for the class. This helps to reduce rebuild times and compatibility issues with projects using your code.
But if this ever happened it would almost certainly because you modified or added some data members, so you'd have to modify the header anyway. And, frankly, such a substantial change to a class's semantics warrants a bit of a careful eye anyway. I don't see the benefit in making code as verbose as possible just for the sake of making changes that shouldn't be completely transparent, transparent.
The compiler inserts code into the beginning of the constructor that initializes the VPTR. Is this operation influenced by whether the constructor is the default one or it is explicitly declared? Is there any difference between the two?
It will always be inserted, it has to be for polymorphism to work, at least the way compilers typically have it implemented. It will be initialized always, the constructors you declare (or don't declare) are irrelevant.
Or, hey, maybe it won't (although I do not know any compilers that behave this way), all you need to care about is that polymorphism works, and will always work no matter what constructors you have declared.
Some days ago, while reading Standard C++ news I've read the post about Defaulted functions in C++11, in that article is mentioned that the user-defined constructor is less efficient than the one generated by the compiler:
The user-defined default constructor is less efficient than the compiler implicitly defined default constructor.
Continuing the reading, there's an example where an user-defined constructor is marked as default, and then says:
the explicitly defaulted constructor is more efficient than a manually programmed default constructor.
I don't understand these assertions, so I was wondering:
Why a user-default constructor (or special member function) would be less efficient than the compiler implicitly defined one?
How is the efficiency improved by explicitly defaulting a constructor (or special member function)?
What guidelines I must follow to choose to default a constructor (or special member function) and how the efficiency affects this decision?
I think a better statement is that a user-defined default constructor MAY be less efficient than a compiler generated out.
For example, when it's generating a default constructor internally the compiler may be able to make assumptions and optimizations that it can't make for a user-defined contstructor (side-effects come to mind).
Also keep in mind that a user-defined default constructor could do totally different work that default-constructing all its members, resulting in it being less efficient (but also more correct). This doesn't seem to be the case in the link you provided however.
And we all know, that if it's written on internet then it is must be right... Wait, do we?
In the article where I found the first assertion of less efficient, the author tells the truth. Though you seem to misinterpret it -- in the example it refers to the hand-crafted ctor uses assignment. For no good reasons, and going against 2 decade old guidelines.
Next instance, same case. (As a practical note I shall add, that for any compiler claiming to have optimizations I expect the same assy output even for that form...)
I see no reason why the proper handwritten ctor would be different from the defaulted one in any ways, including efficiency. OTOH if they are identical why on earth write it? I'm all too happy that compiler makes it for me. And finally I can even control it in some ways I previously could not. Could use more of such functions. ;-)
Given that a class actually is moveable, manually implementing the move constructor and move assignment operator for a class quickly become tedious.
I was wondering when doing so is actually a heavy, heavy, premature optimization?
For instance, if a class only has trivial POD data or members that themselves have move constructor and move assignment operator defined, then I'd guess that the compiler will either just optimize the shit out of the lot (in the case of PODs) and otherwise use the members' move constructor and move assignment operator.
But is that guaranteed? In what scenarios should I expect to explicitly need to implement a move constructor and move assignment operator?
EDIT: As mentioned below by Nicol Bolas in a comment to his answer at https://stackoverflow.com/a/9966105/6345, with Visual Studio 11 Beta (and before) no move constructor or move assignment operator is ever automatically generated. Reference: http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx
If you find yourself implementing, any of:
destructor
copy constructor
copy assignment
Then you should be asking yourself if you need to implement move construction. If you "= default" any of the above, you should be asking yourself if you should then also "= default" the move members.
Even more importantly, you should be documenting and testing your assumptions, for example:
static_assert(std::is_nothrow_default_constructible<A>::value, "");
static_assert(std::is_copy_constructible<A>::value, "");
static_assert(std::is_copy_assignable<A>::value, "");
static_assert(std::is_nothrow_move_constructible<A>::value, "");
static_assert(std::is_nothrow_move_assignable<A>::value, "");
static_assert(std::is_nothrow_destructible<A>::value, "");
First, move semantics only help for classes that hold resources of any kind. "Flat" classes don't benefit from it at all.
Next, you should build your classes out of "building blocks", like vector, unique_ptr and the likes, that all deal with the nitty-gritty low-level detail of resources. If your class is done as such, you won't have to write anything at all since the compiler will generate the members correctly for you.
If you need to write a destructor for, say, logging, generation of move ctors will be disabled, so you need a T(T&&) = default; for compilers that support it. Otherwise, this is one of the only places were to write such a special member yourself (well, except if you write such a "building block").
Note that the logging in the destructor and constructor can be done an easier way. Just inherit from a special class that logs on construction / destruction. Or make it a member variable. With that:
tl;dr Let the compiler generate the special member for you. This also counts for copy constructor and assignment operator, aswell as the destructor. Don't write those yourself.
(Okay, maybe the assignment operators, if you can identify them as a bottle neck and want to optimize them, or if you want special exception safety or somesuch. Though, the "building blocks" should already provide all that.)
Do it every time the default behavior is undesirable or every time the default ones have been deleted and you still need them.
The compiler default behavior for move is call the member and base move. For flat classes / buil-in types this is just like copy.
The problem is typically present with classes holding pointers or value representing resources (like handle, or particular indexes etc) where a move requires to copy the values in the new place, but also to set the old place to some "null state value" recognizable by the destructor. In all other cases, the default behavior is OK.
The problem may also arise when you define a copy (and the compiler deletes the default move) or a move (and the compiler deletes the default copy), and you need them both. In these cases, re-enabling the default may suffice.
In what scenarios should I expect to explicitly need to implement a move constructor and move assignment operator?
Under the following cases:
When you are using Visual Studio 10 or 11. They implement r-value references, but not compiler generated move semantics. So if you have a type that has members that need moving or even contains a moveable type (std::unique_ptr, etc), you must write the move yourself.
When you might need copy constructors/assignment operators and/or a destructor. If your class contains something that made you manually write copy logic or needs special cleanup in a destructor, odds are good that you'll need move logic too. Note that this includes deleting copy mechanisms (Type(const Type &t) = delete;). If you don't want to copy the object, then you probably need move logic or to delete the move functions too.
As others have said, you should try to keep the number of types that need explicit move or copy mechanisms to a bare minimum. Put these in utility "leaf" classes, and have most of your classes rely on the compiler-generated copy and move functions. Unless you're using VS, where you don't get those...
Note: a good trick with move or copy assignment operators is to take them by value:
Type &operator=(Type t) { std::swap(*this, t); return *this; }
If you do this, it will cover both move and copy assignment in one function. You still need separate move and copy constructors, but it does reduce the number of functions you have to write to 4.
The downside is that you're effectively copying twice if Type is made of only basic types (first copy into the parameter, second in swap). Of course, you have to implement/specialize swap, but that's not difficult.
I'm sorry. I may have missed the point of your question. I'm taking your question to mean copy constructors.
Back in the 1990s when I learned C++, I was taught always to write a copy constructor when designing a class. Otherwise, and this may have changed with newer versions of the compiler, C++ will generate a copy constructor for you in the situations that require one.
That default copy constructor may not always work the way you want. This would especially be true if your class contains pointers, or you otherwise do not want the default byte-wise copy of a default copy constructor.
Finally, I was taught that by writing a copy constructor, you are taking exact control over how you want your class copied.
I hope this helps.
Some of my colleagues prefer to explicitly initialize std::auto_ptr to 0 in constructor initialization list, but it will be initialized to 0 in it's constructor without any explicit initialization. So is there any reason to do it?
#include <memory>
class A
{
A() : SomePtr(0)
{
}
private:
std::auto_ptr<SomeType> SomePtr;
};
No, the default constructor of std::auto_ptr does exactly that, so doing it explicitly is not necessary. In any case, it's a matter of style and you should be consistent. For instance, would you explicitly call the default constructor of a member vector in the constructor initialization list?
As a side note, std::auto_ptr is deprecated in the upcoming standard
Psychology.
For built-in types, you probably already know they are uninitialized unless you do so explicitly. For classes, this is not the case.
A strive to consistency results in explicit initialization everywhere. This allows you to forget if A::SomePtr is a built-in or a class type. Pretty useless, imho, since the amount of built-in types is quite limited.
One reason maybe clarity, but that should be the only one. I myself prefer not to write unneccessary intialization, especially if that completely spares me from writing a default constructor for the surrounding class and just let the compiler do its job. Whereas it's merely a matter of style, I think too much over-paranoia does even harm the clarity of the code.