I've got a function that takes a pointer to an object of a custom class (actually pointers to a base class such that polymorphism works). Within the calling routine this object however is exclusively needed for the purpose of this call, i.e. is temporary. For example like this:
class A { /** stuff */ };
class B : public A { /** stuff */ };
void doSomething( const A* const _p ) { /** stuff */ }
void callingRoutine()
{
A* tempPointer = new B;
doSomething( tempPointer );
delete tempPointer;
}
Now, since I really only need the object of type B
within the call to doSomething
, is there a way to do it in one line? Doing
doSomething( new B );
creates memory leaks (valgrind says so). Or would
doSomething( &B );
be the recommended way? The latter compiles but gives warnings about passing pointers to temporary objects. This is what I want to do, but would it be safe this way?
The cleanest way is to do
B b;
doSomething(&b);
But what you really should write depends of what the doSomething
function does. If it's fine to destruct b
at the end of callingRoutine
, then it's the faster and cleaner way to do this, because allocating on the stack is faster than new
and does not require you to delete b
afterwards.
If you can change the signature of the called function, change it to:
void doSomething( A const& obj );
Then you can call it with:
doSomething( B() );
If you can't, should declare a local variable:
void callingRoutine()
{
B temp;
doSomething( &temp );
}
If the calling function is longer, and it is a problem if the temp is
not immediately destructed, you can enclose it in additional {...}
:
void callingRoutine()
{
{
B temp;
doSomething( &temp );
}
// More code here...
}
Generally speaking, however, if this is necessary, your functions are probably too long.
In your case, you can use automatic variable (on stack)
void callingRoutine()
{
B obj;
doSomething( &obj );
} // obj is destroyed automatically
This doesn't give warning. Moreover, you should use new
only when you really want to have reference/access to the memory address outside the function scope for a longer time. Within a function block it doesn't make sense to allocate with new
.
Refer this link from Bjarne's page, where he has pointed the exact example as yours.
By the way if you want just one line, then the solution will not be clean, but here is a work around:
B obj; doSomething( &obj );
I'm a little surprised nobody has pointed out the obvious:
void callingRoutine()
{
doSomething(&B());
}
I have to wonder about the overall design that requires passing in a pointer to an object, but when it's done you apparently ignore the object it operated on, but if you're sure of what you want and the rest of what you're doing, this seems like the simplest, most straightforward way to achieve it.
something like below maybe?
void doSomething( std::auto_ptr<A> _p ) { /** stuff */ }
void callingRoutine()
{
doSomething(std::auto_ptr<A>(new B));
}
The simplest way to solve your problem is to change your code as follows:
void callingRoutine()
{
B temp;
doSomething( &temp );
}
This works because you only need polymorphic access in doSomething() and this is guaranteed by the fact that you pass a pointer to temp by taking its address.
Passing a pointer to a temporary object is generally a bad idea because the object could be destroyed before the callee finished using it. In your example, doSomething()
should return before the object gets deleted or gets out of scope, so, until doSomething
does not store any reference to the object, it's not a problem.
You can cast a temporary value (r-value) to an l-value for the duration of the call or expression:
template<class T>
inline T& l_value(T const& t)
{
return const_cast<T&>(t);
}
struct A {};
void doSomething(const A*);
void foo()
{
doSomething(&l_value(A()));
}
来源:https://stackoverflow.com/questions/6993724/c-ways-to-pass-a-pointer-to-a-temporary-object-on-the-heap-to-a-function