Does RVO work with "new"? - c++

Does copy elision kick in in this situation? In other words, do modern compilers with copy elision avoid to call any copy constructor here?
class BigObj{};
BigObj fun()
{
BigObj b;
return b;
}
int main()
{
BigObj *pb = new BigObj(fun());
}
I aim to store an object in a pointer. The object is returned by a function. I want to store it without copying it.
I can't use c++11

IMO it is not entirely clear what you aim to achieve. If dynamic allocation is what you want to use, then your function should simply:
BigObj * fun()
{
return new BigObj;
}
int main()
{
BigObj *pb = fun();
}
... and save yourself the trouble.
Contrary to the previous revision of the answer, it turned out that the compiler can omit a substantial amount of work as long as it is in a static context that can be thoroughly analyzed:
class C {
public:
C() {qDebug() << "C created";}
C(const C & o) { qDebug() << "C copied"; }
};
C foo() {
C c;
qDebug() << &c;
return c;
}
...
C c = C(foo()); // note that `C c = ` is also copy construction
qDebug() << &c;
The output verifies that both instances have the same address, so even in the context of a local, the instance is actually not stored in the stack frame of foo.
Changing to:
C * cp = new C(foo());
qDebug() << cp;
to my surprise also output the same address, with both the return by value copy and the copy constructor omitted. c in foo is constructed directly in the memory chunk, allocated by new.
In conclusion the C++ compiler is pretty smart at analyzing and doing every possible optimization.
Turning off optimizations in the first and second case respectively:
C created
0x28fd97
C copied
C copied
C copied
0x28fdeb
...
C created
0x28fd97
C copied
C copied
0x34fd00

RVO is among those things that the standard permits, but does not specifically require. That said, most modern compilers (at least, with appropriately optimisation settings enabled) will implement it. If you want a guarantee, however, you will need to read your compiler documentation.
Since the aim is to dynamically allocate an object anyway, I would simply change the example so the called function does dynamic allocation. Instead of (the OP's code);
BigObj fun()
{
BigObj b;
// presumably the point of fun() is that some initialisation
// of b occurs here
return b;
}
int main()
{
BigObj *pb = new BigObj(fun());
}
I would simply use
BigObj *fun()
{
BigObj *b = new BigObj;
// presumably the point of fun() is that some initialisation
// of *b occurs here
return b;
}
int main()
{
BigObj *pb = fun();
}
and eliminate the potential copying of a BigObj all together. The only thing that is being copied around is the value of a pointer. The compiler therefore does not rely on presence of C++11 move constructors to optimise the above, since it avoids unnecessary creation and copying of objects, so this meets the OPs need to not use C++11.
Obviously, in either case, it would be good practice to match the usage of operator new with a corresponding operator delete.

Related

How to call parameterized constructor of member object variable in a class' default constructor in C++?

I want to initialize member object variables in the default constructor of the class.
Let's consider the following,
class ABC {
ABC(int A, int B) {
a = A;
b = B;
}
int a;
int b;
};
class Foo {
Foo();
ABC m_obj1;
};
From the above example, I would like to initialize "obj1" in "Foo::Foo()".
One of the restrictions I have is that I cannot do so in the initializer list, as I need to do some computation before I could initialize the member. So the option available (ASFAIK) is to do so in the body of the default constructor only.
Any inputs, how could I do this?
Edit: Restricting to C++11
Would this be a correct way,
Foo:Foo() {
int x = 10;
int y = 100;
m_Obj1(x, y); //Is this correct? <--------
}
Depending on your exact problem and requirements, multiple solutions might be available:
Option 1: Use a function to do the computations and call Foo constructor
Foo makeFoo()
{
// Computations here that initialize A and B for obj1 constructor
return Foo(A, B)
}
Option 2: Call a function that does the computations and initialize obj1 in Foo member initializer list
ABC initABC() {
// Some computations
return ABC(A, B)
}
Foo() : obj1(initABC()) {}
Option 3: Dynamically allocate obj1, for instance with a std::unique_ptr
Option 4: Use std::optional or an emulated c++11 version as shown by other answers
You simply call the base constructor inside the initializer list of the derived constructor. The initializer list starts with ":" after the parameters of the constructor. See example code!
There is no problem to call functions inside the initializer list itself.
int CallFunc1(int x) { return x*2; }
int CallFunc2(int y) { return y*4; }
class ABC {
public:
ABC(int A, int B):a{CallFunc1(A)},b{CallFunc2(B)} {
std::cout << "Constructor with " << a << " " << b << " called" << std::endl;
}
private:
int a;
int b;
};
class Foo {
public:
Foo(): obj1(1,2){}
Foo( int a, int b): obj1(a, b){}
private:
ABC obj1;
};
int main()
{
Foo foo;
Foo fooo( 9,10);
}
edit:
The best method I can think of for your case is a copy constructor, being more specific on what you need to store helps a lot since if it is just two ints inside a class dynamic allocation is not worth it, the size of the object being constructed makes a difference to what method is best, copy constructors can be slower with much larger data types as the object has to be created twice: once when it is automatically constructed in the parent objects constructor and again when a temporary object is created and all the values have to be copied, which can be slower then dynamically allocating if the size is larger.
As far as I'm aware all objects in a class are automatically initialized/allocated in the constructor so sadly dynamic memory use may be your best bet here.
If you are fine with having the object initialized but empty so you know it is not 'ready' yet you can later fill it with useful data when you would have wanted to initialize it. This can be done with default constructors that set the things inside the object to null values or something similar so you know the object hasn't been properly initialized yet. Then before using the object you can check whether it has been initialized by checking for the null values or by having put a bool in the object that tells you whether it is initialized. Dynamically allocated would still be better in my opinion and makes the code look cleaner overall as all you need to store is a null pointer until the object is needed and then allocated and set to the pointer. It is also very easy to check if the pointer is equal to nullptr to know the state of your object.
Dynamically allocating memory may be a hassle since you have to make sure to get rid of memory leaks and it is slightly slower than using the stack, but it is a necessary skill for c++ since the stack is not enough when making programs that use more than the few available megabytes of data on the stack so if you are doing this simply to avoid the hassle I recommend learning it properly. It would be nice if you could be more specific about what kind of object you want to do this with or if you just want an answer that works for most cases.
eg:
*ABC obj1 = nullptr;
...object is needed
obj1 = new(ABC(constructor stuff));
...obj1 isn't needed
delete obj1;
or c++ automatically deletes it when the program closes.

How to use virtual functions in derived objects without new?

I would like to use virtual functions of objects of different classes (derived from the same base class) without a) constructing all the objects or b) using new. Please see the code example:
#include <iostream>
class A{
public:
virtual void p(void){std::cout << "Im A" << std::endl;};
};
class B : public A{
public:
virtual void p(void) override {std::cout << "Im B" << std::endl;};
};
class C : public A{
public:
virtual void p(void) override {std::cout << "Im C" << std::endl;};
};
int main(){
bool cond = true; // some condition
A* o1;
if (cond) o1 = new B(); else o1 = new C();
o1->p(); // will call correct p(), i.e. either B::p or C::p but not A::p
A o2 = B();
o2.p(); // will call A::p
A* o3;
B tmp1; C tmp2; // construct both objects altough only one is needed
if (cond) o3 = &tmp1; else o3 = &tmp2;
o3->p(); // will call correct p(), i.e. either B::p or C::p but not A::p
A* o4;
if (cond) {B tmp; o4 = &tmp;} else {C tmp; o4 = &tmp;} // uses address of local variable
o4->p(); // will call correct p(), i.e. either B::p or C::p but not A::p
return 0;
}
I want the behavior of o1 but without calling new. o2 doesnt work (calls function of base class and if base class is abstract it doesnt work at all). o3 works but constructs all the different objects although only one is needed. o4 kinda "works" but uses a reference to a local variable outside of its scope.
What would be the correct / best / modern C++ way to do it?
It will be better to use a helper function when you want to avoid using new but be able to use different derived types based on some condition.
void do_stuff(A& obj)
{
}
int main()
{
bool cond = true; // some condition
if (cond)
{
B tmp;
do_stuff(tmp);
}
else
{
C tmp;
do_stuff(tmp);
}
return 0;
}
How to use virtual functions in derived objects without new
Like this:
B b;
C c;
A& a = cond ? b : c;
a.p();
without a) constructing all the objects
You can also do this:
if (cond) {
B b;
b.p();
} else {
C c;
c.p();
}
At this point it doesn't really matter that the function is virtual though since we are using static dispatch. Which is better than dynamic dispatch.
o4 kinda "works" but uses a reference to a local variable outside of its scope.
I.e. the behaviour of the program is undefind i.e. it doesn't work at all.
If using placement new is acceptable, you can use a union to hold the storage, then construct the proper member based on the condition:
union U {
U() { }
B b;
C c;
};
int test(bool cond) {
U u;
A *a2;
if (cond)
a2 = new (&u.b) B;
else
a2 = new (&u.c) C;
a2->p();
return 0;
}
The constructor in the union is necessary since the default constructor will be implicitly deleted due to the presence of non-trivial default constructors for the members of the union.
You'll also have to manually destroy your objects when you're done.
For starters this code snippet
A* o4;
if (cond) {B tmp; o4 = &tmp;} else {C tmp; o4 = &tmp;} // uses address of local variable
o4->p(); // will call correct p(), i.e. either B::p or C::p but not A::p
has undefined behavior because outside the if statement the pointer o4 is invalid due to the fact that the local object tmp is not alive outside the scopes of the if sub-statement.
As for this code snippet
A o2 = B();
o2.p(); // will call A::p
then you should use a reference to an object of the type B. For example
B b;
A &o2 = b;
o2.p();
As for the code snippet with the pointer o1 then in any case pointed objects must exists. Either they will be created dynamically as in your example or you can create the both locally and then depending on the condition set the pointer to one of them.
If you're worried about using new because of memory management, just use a std::shared_ptr instead:
int main(){
bool cond = true; // some condition
std::shared_ptr<A> o1;
if(cond) {
o1 = std::make_shared<B>();
} else {
o1 = std::make_shared<C>();
}
o1->p();
return 0;
}
Prints:
Im B
Working example
Note: I was originally going to suggest an std::unique_ptr instead, however I didn't think they were copyable. But I was wrong. std::unique_ptrs will work too.
Note 2: you will need C++14 or later to use std::make_shared() or std::make_unique, but new will work in C++11. That violates your rule of not using new, but at least it does manage memory for you.
If you want to avoid new mainly to avoid the extra cleanup code and potential bugs from dangling pointers, double deletes, etc., just use std::unique_ptr:
std::unique_ptr<A> o1;
if (cond)
o1 = std::make_unique<B>();
else
o1 = std::make_unique<C>();
o1->p();
This will do essentially the same as the code using new, but behind the scenes, and also does the delete for you when o1 goes out of scope.
If you have a performance-critical code bottleneck and want to avoid the overhead of the heap memory allocation and deallocations used by new, things get trickier, but you could do it with something like:
using B_or_C_type = std::variant<B,C>;
auto o5 = cond ? B_or_C_type{B{}} : B_or_C_type{C{}};;
std::visit(std::mem_fn(&A::p), o5);
On typical systems, this code will avoid using any heap memory at all, instead using stack memory large enough to hold the larger of B or C. std::variant has the logic to act like a union but making sure only the correct type actually gets used. std::visit applies any functor to a variant, as long as the functor can be called with every type in the variant. Note if you define a variant variable with no initializer, it creates an object with the first type, though it can be reassigned to a different-typed object later. (If creating that default object isn't possible or should be avoided, you could use std::monostate as the first dummy type - but then using std::visit gets trickier.)

Should we return pointer to a vector from a function? [duplicate]

I know the title sounds familiar as there are many similar questions, but I'm asking for a different aspect of the problem (I know the difference between having things on the stack and putting them on the heap).
In Java I can always return references to "local" objects
public Thing calculateThing() {
Thing thing = new Thing();
// do calculations and modify thing
return thing;
}
In C++, to do something similar I have 2 options
(1) I can use references whenever I need to "return" an object
void calculateThing(Thing& thing) {
// do calculations and modify thing
}
Then use it like this
Thing thing;
calculateThing(thing);
(2) Or I can return a pointer to a dynamically allocated object
Thing* calculateThing() {
Thing* thing(new Thing());
// do calculations and modify thing
return thing;
}
Then use it like this
Thing* thing = calculateThing();
delete thing;
Using the first approach I won't have to free memory manually, but to me it makes the code difficult to read. The problem with the second approach is, I'll have to remember to delete thing;, which doesn't look quite nice. I don't want to return a copied value because it's inefficient (I think), so here come the questions
Is there a third solution (that doesn't require copying the value)?
Is there any problem if I stick to the first solution?
When and why should I use the second solution?
I don't want to return a copied value because it's inefficient
Prove it.
Look up RVO and NRVO, and in C++0x move-semantics. In most cases in C++03, an out parameter is just a good way to make your code ugly, and in C++0x you'd actually be hurting yourself by using an out parameter.
Just write clean code, return by value. If performance is a problem, profile it (stop guessing), and find what you can do to fix it. It likely won't be returning things from functions.
That said, if you're dead set on writing like that, you'd probably want to do the out parameter. It avoids dynamic memory allocation, which is safer and generally faster. It does require you have some way to construct the object prior to calling the function, which doesn't always make sense for all objects.
If you want to use dynamic allocation, the least that can be done is put it in a smart pointer. (This should be done all the time anyway) Then you don't worry about deleting anything, things are exception-safe, etc. The only problem is it's likely slower than returning by value anyway!
Just create the object and return it
Thing calculateThing() {
Thing thing;
// do calculations and modify thing
return thing;
}
I think you'll do yourself a favor if you forget about optimization and just write readable code (you'll need to run a profiler later - but don't pre-optimize).
Just return a object like this:
Thing calculateThing()
{
Thing thing();
// do calculations and modify thing
return thing;
}
This will invoke the copy constructor on Things, so you might want to do your own implementation of that. Like this:
Thing(const Thing& aThing) {}
This might perform a little slower, but it might not be an issue at all.
Update
The compiler will probably optimize the call to the copy constructor, so there will be no extra overhead. (Like dreamlax pointed out in the comment).
Did you try to use smart pointers (if Thing is really big and heavy object), like shared_ptr:
std::shared_ptr calculateThing()
{
std::shared_ptr<Thing> thing(new Thing);
// .. some calculations
return thing;
}
// ...
{
std::shared_ptr<Thing> thing = calculateThing();
// working with thing
// shared_ptr frees thing
}
One quick way to determine if a copy constructor is being called is to add logging to your class's copy constructor:
MyClass::MyClass(const MyClass &other)
{
std::cout << "Copy constructor was called" << std::endl;
}
MyClass someFunction()
{
MyClass dummy;
return dummy;
}
Call someFunction; the number of "Copy constructor was called" lines that you will get will vary between 0, 1, and 2. If you get none, then your compiler has optimised the return value out (which it is allowed to do). If you get don't get 0, and your copy constructor is ridiculously expensive, then search for alternative ways to return instances from your functions.
Firstly you have an error in the code, you mean to have Thing *thing(new Thing());, and only return thing;.
Use shared_ptr<Thing>. Deref it as tho it was a pointer. It will be deleted for you when the last reference to the Thing contained goes out of scope.
The first solution is very common in naive libraries. It has some performance, and syntactical overhead, avoid it if possible
Use the second solution only if you can guarantee no exceptions will be thrown, or when performance is absolutely critical (you will be interfacing with C or assembly before this even becomes relevant).
I don't want to return a copied value because it's inefficient
This may not be true. Compilers can do optimisation to prevent this copying.
For example, GCC does this optimisation. In the following program, neither move constructor nor copy constructor are called, since no copying or moving is done. Also, notice the address of c. Even though the object c is instantiated inside the function f(), c resides in the stack frame of main().
class C {
public:
int c = 5;
C() {}
C(const C& c) {
cout << "Copy constructor " << endl;
}
C(const C&& c) noexcept {
cout << "Move Constructor" << endl;
}
};
C f() {
int beforeC;
C c;
int afterC;
cout << &beforeC << endl; //0x7ffee02f26ac
cout << &c << endl; //0x7ffee02f2710 (notice: even though c is instantiated inside f(), c resides in the stack frame of main()
cout << &afterC << endl; //0x7ffee02f26a8
return c;
}
C g() {
C c = f(); ///neither copy constructor nor move constructor of C are called, since none is done
cout << &c << endl; //0x7ffee02f2710
return c;
}
int main() {
int beforeC;
C c = g(); ///neither copy constructor nor move constructor of C are called, since none is done
int afterC;
cout << &beforeC << endl; //0x7ffee02f2718
cout << &c << endl; //0x7ffee02f2710 (notice:even though c is returned from f,it resides in the stack frame of main)
cout << &afterC << endl; //0x7ffee02f270c
return 0;
}
I'm sure a C++ expert will come along with a better answer, but personally I like the second approach. Using smart pointers helps with the problem of forgetting to delete and as you say, it looks cleaner than having to create an object before hand (and still having to delete it if you want to allocate it on the heap).

Can creation of composite objects from temporaries be optimised away?

I've asked a few questions which have touched around this issue, but I've been getting differing responses, so I thought best to ask it directly.
Lets say we have the following code:
// Silly examples of A and B, don't take so seriously,
// just keep in mind they're big and not dynamically allocated.
struct A { int x[1000]; A() { for (int i = 0; i != 1000; ++i) { x[i] = i * 2; } };
struct B { int y[1000]; B() { for (int i = 0; i != 1000; ++i) { y[i] = i * 3; } };
struct C
{
A a;
B b;
};
A create_a() { return A(); }
B create_b() { return B(); }
C create_c(A&& a, B&& b)
{
C c;
c.a = std::move(a);
c.b = std::move(b);
return C;
};
int main()
{
C x = create_c(create_a(), create_b());
}
Now ideally create_c(A&&, B&&) should be a no-op. Instead of the calling convention being for A and B to be created and references to them passed on stack, A and B should created and passed in by value in the place of the return value, c. With NRVO, this will mean creating and passing them directly into x, with no further work for the function create_c to do.
This would avoid the need to create copies of A and B.
Is there any way to allow/encourage/force this behavior from a compiler, or do optimizing compilers generally do this anyway? And will this only work when the compiler inline the functions, or will it work across compilation units.
(How I think this could work across compilation units...)
If create_a() and create_b() took a hidden parameter of where to place the return value, they could place the results into x directly, which is then passed by reference to create_c() which needs to do nothing and immediately returns.
There are different ways of optimizing the code that you have, but rvalue references are not one. The problem is that neither A nor B can be moved at no cost, since you cannot steal the contents of the object. Consider the following example:
template <typename T>
class simple_vector {
typedef T element_type;
typedef element_type* pointer_type;
pointer_type first, last, end_storage;
public:
simple_vector() : first(), last(), end_storage() {}
simple_vector( simple_vector const & rhs ) // not production ready, memory can leak from here!
: first( new element_type[ rhs.last - rhs.first ] ),
last( first + rhs.last-rhs.first ),
end_storage( last )
{
std::copy( rhs.first, rhs.last, first );
}
simple_vector( simple_vector && rhs ) // we can move!
: first( rhs.first ), last( rhs.last ), end_storage( rhs.end_storage )
{
rhs.first = rhs.last = rhs.end_storage = 0;
}
~simple_vector() {
delete [] rhs.first;
}
// rest of operations
};
In this example, as the resources are held through pointers, there is a simple way of moving the object (i.e. stealing the contents of the old object into the new one and leaving the old object in a destroyable but useless state. Simply copy the pointers and reset them in the old object to null so that the original object destructor will not free the memory.
The problem with both A and B is that the actual memory is held in the object through an array, and that array cannot be moved to a different memory location for the new C object.
Of course, since you are using stack allocated objects in the code, the old (N)RVO can be used by the compiler, and when you do: C c = { create_a(), create_b() }; the compiler can perform that optimization (basically set the attribute c.a on the address of the returned object from create_a, while when compiling create_a, create the returned temporary directly over that same address, so effectively, c.a, the returned object from create_a and the temporary constructed inside create_a (implicit this to the constructor) are the same object, avoiding two copies. The same can be done with c.b, avoiding the copying cost. If the compiler does inline your code, it will remove create_c and replace it with a construct similar to: C c = {create_a(), create_b()}; so it can potentially optimize all copies away.
Note on the other hand, that this optimization cannot be completely used in the case of a C object allocated dynamically as in C* p = new C; p->a = create_a();, since the destination is not in the stack, the compiler can only optimize the temporary inside create_a and its return value, but it cannot make that coincide with p->a, so a copy will need to be done. This is the advantage of rvalue-references over (N)RVO, but as mentioned before you cannot do use effectively rvalue-references in your code example directly.
There are two kinds of optimization which can apply in your case:
Function Inlining (In the case of A, B, and C (and the A and B it contains))
Copy elision (C (and the A and B it contains) only, because you returned C by value)
For a function this small, it's probably going to be inlined. Most any compiler will do it if it exists in the same translation unit, and good compilers like MSVC++ and G++ (and I think LLVM but I'm not sure on that one) have whole-program-optimization settings which will do it even across translation units. If the function is inlined, then yes, the function call (And the copy that comes with it) aren't going to occur at all.
If for some reason the function doesn't get inlined (i.e. you used __declspec(noinline) on MSVC++), then you're still going to be eligible for the Named Return Value Optimization (NRO), which good C++ compilers (again, MSVC++, G++, and I think LLVM) all implement. Basically, the standard says that the compilers are allowed to not perform the copy on return if they can avoid doing so, and they will usually emit code that avoids it. There are some things you can do to deactivate NRVO, but for the most part it's a pretty safe optimization to rely on.
Finally, profile. If you see a performance problem, then figure out something else. Otherwise I'd write things in the ideomatic way and replace them with more performant constructs if and only if you need to.
Isn't the obvious thing to do to give C a constructor and then say:
C create_c(const A & a, const B & b)
{
return C( a, b );
}
which has lots of possibilities for optimisation. Or indeed get rid of the create function. I don't think this is a very good motivating example.

How to "return an object" in C++?

I know the title sounds familiar as there are many similar questions, but I'm asking for a different aspect of the problem (I know the difference between having things on the stack and putting them on the heap).
In Java I can always return references to "local" objects
public Thing calculateThing() {
Thing thing = new Thing();
// do calculations and modify thing
return thing;
}
In C++, to do something similar I have 2 options
(1) I can use references whenever I need to "return" an object
void calculateThing(Thing& thing) {
// do calculations and modify thing
}
Then use it like this
Thing thing;
calculateThing(thing);
(2) Or I can return a pointer to a dynamically allocated object
Thing* calculateThing() {
Thing* thing(new Thing());
// do calculations and modify thing
return thing;
}
Then use it like this
Thing* thing = calculateThing();
delete thing;
Using the first approach I won't have to free memory manually, but to me it makes the code difficult to read. The problem with the second approach is, I'll have to remember to delete thing;, which doesn't look quite nice. I don't want to return a copied value because it's inefficient (I think), so here come the questions
Is there a third solution (that doesn't require copying the value)?
Is there any problem if I stick to the first solution?
When and why should I use the second solution?
I don't want to return a copied value because it's inefficient
Prove it.
Look up RVO and NRVO, and in C++0x move-semantics. In most cases in C++03, an out parameter is just a good way to make your code ugly, and in C++0x you'd actually be hurting yourself by using an out parameter.
Just write clean code, return by value. If performance is a problem, profile it (stop guessing), and find what you can do to fix it. It likely won't be returning things from functions.
That said, if you're dead set on writing like that, you'd probably want to do the out parameter. It avoids dynamic memory allocation, which is safer and generally faster. It does require you have some way to construct the object prior to calling the function, which doesn't always make sense for all objects.
If you want to use dynamic allocation, the least that can be done is put it in a smart pointer. (This should be done all the time anyway) Then you don't worry about deleting anything, things are exception-safe, etc. The only problem is it's likely slower than returning by value anyway!
Just create the object and return it
Thing calculateThing() {
Thing thing;
// do calculations and modify thing
return thing;
}
I think you'll do yourself a favor if you forget about optimization and just write readable code (you'll need to run a profiler later - but don't pre-optimize).
Just return a object like this:
Thing calculateThing()
{
Thing thing();
// do calculations and modify thing
return thing;
}
This will invoke the copy constructor on Things, so you might want to do your own implementation of that. Like this:
Thing(const Thing& aThing) {}
This might perform a little slower, but it might not be an issue at all.
Update
The compiler will probably optimize the call to the copy constructor, so there will be no extra overhead. (Like dreamlax pointed out in the comment).
Did you try to use smart pointers (if Thing is really big and heavy object), like shared_ptr:
std::shared_ptr calculateThing()
{
std::shared_ptr<Thing> thing(new Thing);
// .. some calculations
return thing;
}
// ...
{
std::shared_ptr<Thing> thing = calculateThing();
// working with thing
// shared_ptr frees thing
}
One quick way to determine if a copy constructor is being called is to add logging to your class's copy constructor:
MyClass::MyClass(const MyClass &other)
{
std::cout << "Copy constructor was called" << std::endl;
}
MyClass someFunction()
{
MyClass dummy;
return dummy;
}
Call someFunction; the number of "Copy constructor was called" lines that you will get will vary between 0, 1, and 2. If you get none, then your compiler has optimised the return value out (which it is allowed to do). If you get don't get 0, and your copy constructor is ridiculously expensive, then search for alternative ways to return instances from your functions.
Firstly you have an error in the code, you mean to have Thing *thing(new Thing());, and only return thing;.
Use shared_ptr<Thing>. Deref it as tho it was a pointer. It will be deleted for you when the last reference to the Thing contained goes out of scope.
The first solution is very common in naive libraries. It has some performance, and syntactical overhead, avoid it if possible
Use the second solution only if you can guarantee no exceptions will be thrown, or when performance is absolutely critical (you will be interfacing with C or assembly before this even becomes relevant).
I don't want to return a copied value because it's inefficient
This may not be true. Compilers can do optimisation to prevent this copying.
For example, GCC does this optimisation. In the following program, neither move constructor nor copy constructor are called, since no copying or moving is done. Also, notice the address of c. Even though the object c is instantiated inside the function f(), c resides in the stack frame of main().
class C {
public:
int c = 5;
C() {}
C(const C& c) {
cout << "Copy constructor " << endl;
}
C(const C&& c) noexcept {
cout << "Move Constructor" << endl;
}
};
C f() {
int beforeC;
C c;
int afterC;
cout << &beforeC << endl; //0x7ffee02f26ac
cout << &c << endl; //0x7ffee02f2710 (notice: even though c is instantiated inside f(), c resides in the stack frame of main()
cout << &afterC << endl; //0x7ffee02f26a8
return c;
}
C g() {
C c = f(); ///neither copy constructor nor move constructor of C are called, since none is done
cout << &c << endl; //0x7ffee02f2710
return c;
}
int main() {
int beforeC;
C c = g(); ///neither copy constructor nor move constructor of C are called, since none is done
int afterC;
cout << &beforeC << endl; //0x7ffee02f2718
cout << &c << endl; //0x7ffee02f2710 (notice:even though c is returned from f,it resides in the stack frame of main)
cout << &afterC << endl; //0x7ffee02f270c
return 0;
}
I'm sure a C++ expert will come along with a better answer, but personally I like the second approach. Using smart pointers helps with the problem of forgetting to delete and as you say, it looks cleaner than having to create an object before hand (and still having to delete it if you want to allocate it on the heap).