Copying an object is an expensive operation, especially if the type of the object is not trivial to copy. To avoid creating an unnecessary copy of such object, use const references.
A trivially copyable type is one that can be safely copied and moved using memcpy
and memmove
. This means that the type has a trivial copy constructor, a trivial copy assignment operator, and a trivial destructor. Examples of trivially copyable types include:
A class or struct is considered a POD type if it is trivially copyable and satisfies certain other constraints such as having no user-defined constructors, no private or protected non-static data members, no virtual functions, and no virtual base classes.
// Example 1: Using strings
const string& getStr();
void do_it() {
const string s = getStr(); // unnecessary string copy
// note: `s` can never be modified here
}
// Example 2: Non-trivally copyable type
class A {
A (const A& a); // A used-defined copy constructor makes this class non-trival to copy
const void foo() const; // A const method
};
const A& getRefToA();
void do_it(const Foo& foo) {
A a1 = getRefToA(); // `a1` is never used as a mutable, and still copied. This results in drop in performance.
a1.foo();
A a2 = a1; // An identical expensive copy
a2.foo();
}
// Example 1: Using strings
const string& getStr();
void do_it() {
const string& s = getStr(); // Avoiding copy with const reference
}
// Example 2: Non-trivally copyable type
class A {
A (const A& a); // A used-defined copy constructor makes this class non-trival to copy
const void foo() const; // A const method
};
A& getRefToA();
void do_it(const Foo& foo) {
const A& a1 = getRefToA(); // Avoiding copy with const reference
a1.foo();
const A& a2 = a1;
a2.foo();
}