views:

114

answers:

2

I was reading this http://en.wikipedia.org/wiki/C%2B%2B0x#Modification_to_the_definition_of_plain_old_data

It mentions trivial default constructor, trivial copy constructor, copy assignment operator, trivial destructor. What is trivial and not trivial?

+8  A: 

A constructor of a class A is trivial if all the following are true:

  • It is implicitly defined (compiler synthesized)
  • A has no virtual functions and no virtual base classes
  • All the direct base classes of A have trivial constructors
  • The classes of all the nonstatic data members of A have trivial constructors
Prasoon Saurav
+6  A: 

In simple words a "trivial" special member function literally means a member function that does its job in a very straightforward manner. The "straightforward manner" means different thing for different kinds of special member functions.

For a default constructor and destructor being "trivial" means literally "do nothing at all". For copy-constructor and copy-assignment operator, being "trivial" means literally "be equivalent to simple raw memory copying" (like copy with memcpy).

If you define a constructor yourself, it is considered non-trivial, even if it doesn't do anything, so a trivial constructor must be implicitly defined by the compiler.

In order for a special member function to satisfy the above requirements, the class must have a very simplistic structure, it must not require any hidden initializations when an object is being created or destroyed, or any hidden additional internal manipulations when it is being copied.

For example, if class has virtual functions, it will require some extra hidden initializations when objects of this class are being created (initialize virtual method table and such), so the constructor for this class will not qualify as trivial.

For another example, if a class has virtual base classes, then each object of this class might contain hidden pointers that point to other parts of the very same object. Such a self-referential object cannot be copied by a simple raw memory copy routine (like memcpy). Extra manipulations will be necessary to properly re-initialize the hidden pointers in the copy. For this reason the copy constructor and copy-assignment operator for this class will not qualify as trivial.

For obvious reasons, this requirement is recursive: all subobjects of the class (bases and non-static members) must also have trivial constructors.

AndreyT
Not do anything... Then what is a copy assignment operator? ;)
acidzombie24
Also am i allowed to have a nontrival ctor like (Rect r) { l = r....}
acidzombie24
@acidzombie24: I made some corrections to cover copying member functions. Your second comment is not clear to me. Any user defined constructor is non-trivial, so once you define it, the class is no longer a POD.
AndreyT
Excellent post. I was wondering if i had a struct like `struct Rect1 { int l, r, w, h}; struct Rect2 { int l, t, r, b' Rect2(){} Rect2(Rect1 r) {...} };` would be considered trivial. But i guess not since i am not allowed to define any ctors. I would have thought it is allowed since there is a trivial default ctor and this isnt an assignment or copy operator
acidzombie24
Actually in C++0x case it says `trivial default constructor` so what i want IS allowed in C++0x (maybe older versions but C++0x is guaranteed)
acidzombie24
@acidzombie24: When you declare *any* constructor, you suppress the implicit declaration of the default constructor. So, you class will have *no* default constructor at all. That's how it is in pre-C++0x language. In C++0x, AFAIK, you can force the compiler to generate the default constructor nonetheless, which will require an explicit declaration with keyword `default`, as shown at your link.
AndreyT
@AndreyT: Excellent distinction.
acidzombie24