Reputation: 881
I have this class:
class foo{
public:
foo();
foo(const int& var);
foo(const foo& var);
~foo();
foo retSumOf(const foo& var1, const foo& var2);
private:
int a;
char* x;
};
and this meber function:
foo foo::retSumOf(const foo& var1, const foo& var2){
//Make somehow a foo object,
//lets name it 'result'
result.a = var1.a + var2.a;
return (result);
}
I want to do this in main:
main(){
foo a, b;
foo* c;
a.a = 1;
b.a = 2;
c = retSumOf(a, b);
cout << "sum =" << c->a;
}
without to invoke the (overloaded) copy constructor!
Is there a way in C++ to create an object dynamically from a function and return his address? Without the constructor to delete it at the end of the invocation of retSumOf()?
Upvotes: 1
Views: 343
Reputation: 20730
Just do this
class foo
{
...
friend foo retSumOf(const foo& var1, const foo& var2);
...
};
foo retSumOf(const foo& var1, const foo& var2);
{
foo result;
result.a = var1.a + var2.a;
return (result);
}
and enable compiler optimization.
Since there's only one return statement in your function, and result
is local, the compiler will create it on the stack in the place of the return value, avoiding the copy.
No need to worry about that. (and yes, no need to call "move").
If you want a more "functional" approach, give to foo
a constructor that defines the member values and use accordngly:
class foo
{
// you existing code andd ...
foo(int i, const char* s) :a(i), x(s)
{}
};
so that you can do
foo retSumOf(const foo& var1, const foo& var2)
{ return foo(var1.a + var1.b, nullptr); }
It it even make sense, you can name retSumOf
just operator+
and have c = a+b
;
In any case, avoid to have c
as a naked pointer: it will never be clear who has to delete the received object. It only needs to be a value.
Don't ever use char* as a member: it is not clear who owns the data after an assignment or a copy. Use std::string
instead.
Upvotes: 0
Reputation: 549
You can return the value from the function as a reference to foo
and save it in a const foo&
. The const-reference will prolong the lifespan of the foo
instance to the lifespan of the variable.
foo& foo::retSumOf(const foo& var1, const foo& var2)
...
const foo& c = retSumOf(a, b);
EDIT
Turns out this does not work: http://ideone.com/WM3bIe
Upvotes: 0
Reputation: 6505
There are a couple of ways, first:
You can use the return value as an argument:
void foo::computeSumOf(foo & result, const foo& var1, const foo& var2) ...
Another way is to take advantage of the RVO optimization
foo foo::retSumOf(const foo& var1, const foo& var2)
{
return foo(var1.a + var2.a);
}
//...
foo x = someFoo.retuSomOf(a,b);
Third (if you can use c++ 11) you can use write move constructor and assignment to avoid copy constructor. By doing this you can optimize the unnecessary copy of members and just "move" the memory from one instance to another . You can find more info here.
class foo{
public:
foo(foo && rValue) { ... };
foo& operator = (foo && rValue) { ... };
...
};
foo foo::retSumOf(const foo& var1, const foo& var2){
foo result;
//same code
return result;
}
Lastly, you can use shared_ptr or other smart pointers (like intrusive_ptr)
std::shared_ptr<foo> foo::retSumOf(const foo& var1, const foo& var2){
std::shared_ptr<foo> result = new foo;
result->a = ...
return result;
}
Upvotes: 3
Reputation: 1151
Modify the function as follows:
foo* foo::retSumOf(const foo& var1, const foo& var2){
//Make somehow a foo object,
//lets name it 'result'
foo* result = new foo();
result->a = var1.a + var2.a;
return (result);
}
Upvotes: 3
Reputation: 23510
Not sure if my answer is right but it actually seems to work all the time for me:
#include <iostream>
class Foo
{
public:
Foo() {std::cout<<"HEY!";}
~Foo() {}
};
Foo&& GetFoo()
{
return std::move(Foo());
}
int main()
{
GetFoo();
return 0;
}
I usually just move an object created within a function.. Just so that I can avoid pointers as much as possible.. Otherwise I'd use a Smart pointer but the above is what I normally do.
Upvotes: -1
Reputation: 71989
Why?
Yes, you can return a (smart) pointer, like Jeremy says, but why would you do that? Why not instead correctly implement the copy and move functions? You already have a constructor; by the rule of five you should implement the other four functions anyway, or suppress them.
Upvotes: 5
Reputation: 3005
You could either declare it as static:
static myClass objName;
or use new (preferred):
myClass* objName = new myClass;
return objName
If you use the second method, you need to modify your function to return a pointer, rather than an object.
Upvotes: 1