Reputation:
In trying to understand this answer, it seems that new
can be classified as a "copy constructor" and delete
sometimes as a "trivial destructor".
I can find next to nothing (that I can quickly grasp) on "trivial assignment" except that it is "trivial if it is implicitly declared, if its class has no virtual member functions or virtual base classes, and if its direct base classes and embedded objects have a trivial assignment operator".
I found a question on yahoo about implicit declaration, but to my surprise, it did not answer.
My brain hurts after reading about virtual member functions.
Besides, I'm a monkey-see-monkey-do programmer, so the only way I'm going to get this is to see it in action. Please explain with respect to the above definition of "trivial" by using the example provided in the first answer, that std::string
has a trivial assignment operator by using new
or delete
or for a less apparent reason.
Upvotes: 1
Views: 3412
Reputation: 10893
New can use a copy constructor, and delete uses a destructor. The copy constructor or destructor may be trivial.
That being said, there is a STRONG chance that you will not need to worry about whether a constructor/destructor is trivial for a long time.
new
calls a constructor to construct the object. If the one argument to the constructor of type T
is an instance of T
that is a copy constructor: you are trying to construct an instance of one object from another
class Foo
{
public:
Foo(int x) // not a copy constructor
: mX(x)
{ }
Foo(const Foo& inOther) // copy constructor
: mX(inOther.mX)
{ }
private:
int mX;
};
class Bar
{
public:
Bar(int x)
: mX(x)
{ }
// no copy constructor specified.. C++ will build an implicit one for you
private:
int mX;
}
};
Foo a(1); // uses the first constructor (not a copy)
Foo b(a); // uses a copy constructor
Foo c = a; // copy constructor
Foo* d = new Foo(1); // construct a new instance of Foo (not a copy)
Foo* e = new Foo(a); // copy
Bar f(1); // normal constructor
Bar g(f); // IMPLICIT copy constructor
If your class does not have a copy constructor, like Bar, C++ usually provides you one (always provides you one unless you have an explicit
constructor or delete the copy constructor with a C++11 keyword). This copy constructor is very straightforward: it copies each member of your class.
A trivial copy constructor is special. A trivial copy constructor can only be created when the copy constructor is implicitly created for you by the compiler and:
If you specify a constructor in your class, it is not trivial, by definition. Foo does not have a trivial copy constructor because it is user defined. Bar has an implicit copy constructor because it is not user defined. The implicit copy constructor IS trivial, because copying mX is trivial (copying ints is trivial).
Similar rules go for destructors. A trivial destructor follows the same rules, and delete
WHat does it do for you? The spec lists a few key behaviors about trivial constructors/destructors. In particular, there's a list of things you can do if you have a trivial constructor and destructor that are illegal otherwise. However, they are all very nuanced, and unimportant to 99.9% of C++ code development. They all deal with situations where you can get away with not constructing or destructing an object.
For example, if I have a union:
union MyUnion {
int x;
ClassA y;
ClassB z;
}
If y and z have trivial constructors and destructors, C+ will write a copy constructor for that union for me. If one of them has a non-trivial constructor/destructor, I have to write the copy constructor for the union myself.
Another thing you can do is fast destruction of an array. Usually, when you delete an array, you have to make sure to call the destructor on every item. If you can prove that the destructor of each element is trivial, then you are allowed to skip destroying the elements, and just free the memory. std::vector
does this under the hood (so you don't have to)
Upvotes: 3