I'm quite new to smart pointers and was trying to refactor some existing code to use auto_ptr. The question I have is about double pointers and their auto_ptr equivalent, if that makes sense.
I have a function that accepts a double pointer as its parameter and the function allocates resources for it:
void foo ( Image** img ) { ... *img = new Image(); ...}
This function is then used like this:
Image* img = NULL;
foo ( &img );
...
delete img;
I want to use auto_ptr to avoid having to call delete explicitly. Is the following correct?
void foo ( auto_ptr<Image>* img ) { ... *img = auto_ptr<Image>(new Image()); ...}
and then
auto_ptr<Image> img = NULL;
foo ( &img );
Thanks.
std::auto_ptr<> has weird copy semantics (actually it's move semantics, rather than copy semantics) and is often not what you want when you want a smart pointer. For example, it cannot be put into STL containers.
If your standard library comes with TR1 support, use std::tr1::shared_ptr<> instead. (If it doesn't, use boost's boost::shared_ptr<>, which is what std::tr1::shared_ptr<> was taken from.)
If you want to stick with std::auto_ptr<> for your code, you can pass it into the function per non-const reference:
void foo ( std::auto_ptr<Image>& img ) { ... img.reset(new Image();) ...}
std::auto_ptr<Image> img;
foo ( img );
...
// no need to delete
Or you could just return the pointer:
std::auto_ptr<Image> foo () {return std::auto_ptr<Image> img(new Image();)}
It depends on whether or not your STL's implementaton of auto_ptr overrides the '&' operator to return a pointer-to-pointer (most smart pointer classes tend to, but not all auto_ptr implementations do).
If you really want to re-write your code to pass auto_ptr objects around, then you should do something more like this instead, which would be safer:
void foo ( std::auto_ptr<Image> &img ) { ... img.reset(new Image()); ...}
std::auto_ptr<Image> img;
foo ( img );
Since you are refactoring, I would go one step further and convert the parameter into a return value:
// void foo( Image ** img )
std::auto_ptr<Image> foo() {
std::auto_ptr<Image> tmp( new Image() );
// ...
return tmp;
}
Even if I prefer removing the requirement from the interface (so that the caller can decide to change the code to use any other type of smart pointer at will):
Image* foo() {
std::auto_ptr<Image> tmp( new Image() );
// ...
return tmp.release();
}
int main() {
std::auto_ptr<Image> ptr( foo() );
}
Related
I remember vaguely that python allowed something like
def foo( x ):
....
f = foo( 5 )
Is something like that possible in c++ so that if I have a member function
class C {
void foo( int x ) { ... }
so that I can define a pointer or variable that would effectively point at foo( 5 )
The reason why I want to do this is because I have many listeners that I need to subscribe to a callback and keep information who gets called
class C {
map<int, ptrSender> m_sender;
void subscribe() {
for (const auto& p : m_sender) {
p .second->register( Callback( this, &C::onCall ) )
}
My problem is that the onCall does not return which sender called back, but I would need this information. So, instead of doing something like this
void subscribe() {
m_sender[0]->register( Callback( this, onCall_0 ) );
m_sender[1]->register( Callback( this, onCall_1 ) );
....
void onCall( int sender_id ) { ... }
void onCall_0() { onCall( 0 ); }
void onCall_1() { onCall( 1 ); }
....
I was hoping I could pass something into register that would return a call with a preset argument. Is this possible?
EDIT: I am trying to use a lambda function, but I am running into the following problems
auto setCall= [this]( int v ) { &C::onCall( v ); }
gives the compile error
lvalue required as unary&opeand
This
auto setCall= [this]( int v ) { C::onCall( v ); }
....
p.second->register( Callback( this, &setCall( p.first) ) ); /// <__ error now here
complains again, now in the second line
lvalue required as unary&operand
and this
auto setCall= [this]( int v ) { C::onCall( v ); }
....
p.second->register( Callback( this, setCall( p.first) ) ); /// <__ error now here
complains about invalid use of void expression, but I assume I have to pass in a reference to make the register function happy
Callback seems to be defined as
# define CallBack(obj,func) ProfiledBasicCallBack(obj,fastdelegate::FastDelegate0<void>(obj,func),#func)
Yes, you can use std::bind. Example usage: http://ideone.com/akoWbA.
void foo( int x ) { cout << x << endl; }
auto x = std::bind(foo, 5);
x();
However, with modern C++, you should use a lambda. Like so:
void foo( int x ) { cout << x << endl; }
auto x = []() { foo(5); };
x();
Note that this foo function is outside of the class C in this example. If you wish to contain it inside, then with std::bind you need to pass the instance of the object you wish to call on, e.g.
C c;
auto x = std::bind(&C::foo, &c, 5);
x();
or with lambdas:
C c;
auto x = [&c]() { c.foo(5); };
x();
What you are looking for is std::bind(). It takes one callable object, and gives you another callable object with predefined values for its parameter, and maybe some optional parameters forwarded to it.
A word of warning: this is a fairly steep learning curve. You need to understand templates.
If you want to bind a parameter value to a compile-time constant argument (like 5 in your example), then the problem can be solved by introducing a simple wrapper function that will call your function while passing the desired constant values as corresponding arguments.
But when the argument is a run-time value, then the answer is no: it is generally not possible to create a credible implementation of such function pointer binding in C++ (unless you are using some compiler-specific extension).
However, in C++ you have a variety of alternative tools at your disposal. You can create a function object that will mimic the functionality you desire. Such function object can be created by using std::bind, by using lambda-expressions, or even implemented manually.
The resultant function object will be "callable" and will behave similarly to function pointer at superficial level, but nevertheless it won't be a function pointer, won't be convertible to a function pointer and won't be accepted where a genuine function pointer is required. In other words, if your register method is declared to expect a function pointer as its second argument, then there's nothing you can do here. Neither std::bind, nor lambdas, nor anything else in the language will help you to achieve this kind of parameter binding.
For this reason it is generally a good idea to steer clear of function pointers in such designs and implement such functionality in terms of generic callable objects. The simplest thing to use might be std::function objects in place of raw function pointers.
So I've been working on memory management and have a particular issue when it comes to moving objects that contain function objects that wrap lambda's that capture data. Suppose the following example:
typedef std::function < void( int ) > funcType;
class Something
{
private:
int _myNum = 0;
public:
funcType GetSetIt( )
{
return [&] ( int a )
{
_myNum = a;
};
}
void SeeIt( )
{
std::cout << _myNum << std::endl;
}
int GetIt( )
{
return _myNum;
}
};
And the following operations:
auto destination = ( Something* ) malloc( sizeof( Something ) );
auto alt = ( funcType* ) malloc( sizeof( funcType ) );
auto size = sizeof( funcType );
auto s = new Something( );
auto setIt = s->GetSetIt( );
setIt( 10 );
s->SeeIt( );
auto a = s->GetIt( );
memcpy( destination, s, sizeof( Something ) );
memset(s, 0, sizeof( Something ) );
memcpy( alt, &setIt, sizeof( funcType ) );
memset( &setIt, 0, sizeof( funcType ) ); // point 1
(*alt)( 15 );
destination->SeeIt( );
auto b = destination->GetIt( );
A quick explanation:
Create a new Something and call all of it's members to make sure it's working correctly. Then move it to a new location and delete/clear where it used to exist. Also move the function object to a new location and clean up after. Then, using pointer's to the new locations, call the function object and the methods on the object.
The first issue is that everything is moving along smoothly until I memset the original location of the function object. If you comment out that line (noted with // point 1) you'll notice it does not crash.
This is a little strange to me, but I don't fully understand how function objects are laid out in memory and was hoping for a little light to be shed in that area. I would assume that if I block-copied the entire object to another area and cleared the old space (not deleting it because it's on the stack) that it and all of it's references would be preserved.
The second issue, assuming you've commented out the memset line is that "expected results" are not the same as "desired results". I expect that calling alt will set _myNum on s to 15, and it does. But I want to update alt's pointer to Something (which I usually refer to as it's this pointer) to point to destination. How can I achieve that? Can it be done dependably across compilers? I've been worried that, although I could conceivably find where it's stored and update the value, the solution won't be solid because lambda's can be implemented in a variety of ways across compilers and there may be some "magic" at hand.
Any help or insight into these issues is greatly appreciated. If I'm not clear on what's going on, comment and I'll provide more detail where needed. Thanks in advance!
function is not trivially copyable (3.9p9, 9p6) so you cannot copy it with memcpy. Use the is_trivially_copyable trait to detect whether a type is trivially copyable.
If you want to "move" an object of a non-trivially copyable type from one location to another, use placement new with its move constructor and perform a destructor call on the previous location:
new (*buf) T(std::move(obj));
obj.~T();
You should use placement new and ensure the setter is taken from the copied object:
#include <functional>
#include <iostream>
// ...
int main() {
char source[sizeof(Something)];
char source_setter[sizeof(funcType)];
Something* src = new (source) Something;
// Get the setter from the source object.
funcType* src_setter = new (source_setter) funcType(src->GetSetIt());
(*src_setter)(0);
char destination[sizeof(Something)];
char destination_setter[sizeof(funcType)];
Something* dst = new (destination) Something(*src);
// Get the setter from the destination object.
funcType* dst_setter = new (destination_setter) funcType(dst->GetSetIt());
(*dst_setter)(1);
src->SeeIt();
dst->SeeIt();
src_setter->~funcType();
src->~Something();
dst_setter->~funcType();
dst->~Something();
}
I have a Visual Studio 2008 C++03 project where I would like to use a boost::function object to set the value of a pointer. Something like this:
boost::function< void( int* ) > SetValue;
boost::function< int*() > GetValue;
int* my_value_;
SetValue = boost::bind( my_value_, _1 ); // how should this look?
GetValue = boost::bind( my_value_ ); // and this?
int v;
SetValue( &v );
assert( my_value_ == &v );
int* t = GetValue();
assert( t == my_value_ );
Is there a way to do this or do I need an intermediate function like:
void DoSetValue( int* s, int* v ) { s = v; };
SetValue = boost::bind( DoSetValue, my_value_, _1 );
Thanks
Use Boost.Lambda library:
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
int main()
{
boost::function<void(int*)> SetValue = (boost::lambda::var(my_value) = boost::lambda::_1);
boost::function<int*()> GetValue = boost::lambda::var(my_value);
}
You can find more about using variables in its documentation.
Your first attempt will not work as bind() requires a function (or functor), but you are passing a data pointer, so you need to provide a function that does the work you seek.
Note: if you use C++11, you could use lambdas, to avoid having to create a named function
Note: you need to dereference the pointers in DoSetValue or use references (in which case you need to change the declaration of SetValue as well) -- otherwise the change will not be visible outside the function call
void DoSetValue( int& s, int& v ) { s = v; };
For bind to work that way, you would need a pointer to operator=( int* ). Of course, there is no such thing, so you need an intermediate function.
If you could use lambda or phoenix, there are ways to make a function-object that assigns something to something else. It depends on which library you use, but it would look somewhat like this:
bl::var( my_value_ ) = bl::_1;
I'm working on a C++ API which exports several classes from a DLL.
A public class interface should follow the following conventions:
All functions return an error code.
Output parameters are used for additional return values.
Pass by pointer is used for Output parameters.
Pass by const reference is used for Input parameters (pass by value for primitive types).
When the client should take ownership of output parameter shared_ptr is used, otherwise a normal pointer.
Example interface:
typedef std::shared_ptr<Object> ObjectPtr;
class APIClass
{
ErrorCode SetSomething(int i);
ErrorCode IsSomethingSet(bool* ask);
ErrorCode DoSomething();
ErrorCode GetSomething(ObjectPtr* outObj);
}
Example usage:
ErrorCode res;
ObjectPtr obj;
res = myApiClass->GetSomething(&obj);
GetSomething implementation:
ErrorCode APIClass::GetSomething(ObjectPtr* outObj)
{
ObjectPtr temp(new Object(), CleanUpFunction<Object>);
// Do something with object temp.
...
*outObj= temp;
return OK;
}
Is it save to use a shared_ptr in this way or are there possible issues I should be aware of?
This is fine, but I'd ask whether a shared pointer is really necessary in this case. Mostly because you can't release a pointer from a shared_ptr in any sane way... this can lead to problems later. And shared_ptr really means unspecified or shared ownership of the underlying resource.
I typically document the function and use something like:
// Caller must delete the outObj once done.
ErrorCode APIClass::GetSomething( Object* & outObj )
{
// I use auto_ptr so I can release it later...
// Mostly I hate auto_ptr, but for this its invaluable.
auto_ptr<Object> obj( new Object );
...
outObj = obj.release();
return OK;
}
This way it is up to the client what they want to store the pointer into, and it is clear that ownership of the object passes to the caller.
Client code can then use an appropriate container.
Object * obj_raw;
ErrorCode ec = apiClass.GetSomething( obj_raw )
if( ec!=OK ) { .. do something with ec .. }
shared_ptr<Object> obj( obj_raw );
or
auto_ptr<Object> obj( obj_raw );
or
scoped_ptr<Object> obj( obj_raw);
etc.
Note that this can be made neater if you change your function definition to:
// Caller must delete the return value.
// On error, NULL is returned and e filled in appropriately.
Object* APIClass::GetSomething( ErrorCode & e )
{
auto_ptr<Object> obj( new Object );
..
e = OK;
return obj.release();
}
//Now using it looks like this:
ErrorCode ec;
shared_ptr<Object> obj( apiObject.GetSomething(ec) );
if(!obj)
{
.. do something with ec ..
}
Is it possible to declare a variable in c++ without instantiating it? I want to do something like this:
Animal a;
if( happyDay() )
a( "puppies" ); //constructor call
else
a( "toads" );
Basially, I just want to declare a outside of the conditional so it gets the right scope.
Is there any way to do this without using pointers and allocating a on the heap? Maybe something clever with references?
You can't use references here, since as soon as you'd get out of the scope, the reference would point to a object that would be deleted.
Really, you have two choices here:
1- Go with pointers:
Animal* a;
if( happyDay() )
a = new Animal( "puppies" ); //constructor call
else
a = new Animal( "toads" );
// ...
delete a;
or with a smart pointer
#include <memory>
std::unique_ptr<Animal> a;
if( happyDay() )
a = std::make_unique<Animal>( "puppies" );
else
a = std::make_unique<Animal>( "toads" );
2- Add an Init method to Animal:
class Animal
{
public:
Animal(){}
void Init( const std::string& type )
{
m_type = type;
}
private:
std:string m_type;
};
Animal a;
if( happyDay() )
a.Init( "puppies" );
else
a.Init( "toads" );
I'd personally go with option 2.
You can't declare a variable without calling a constructor. However, in your example you could do the following:
Animal a(happyDay() ? "puppies" : "toads");
You can't do this directly in C++ since the object is constructed when you define it with the default constructor.
You could, however, run a parameterized constructor to begin with:
Animal a(getAppropriateString());
Or you could actually use something like the ?: operator to determine the correct string.
(Update: #Greg gave the syntax for this. See that answer)
I prefer Greg's answer, but you could also do this:
char *AnimalType;
if( happyDay() )
AnimalType = "puppies";
else
AnimalType = "toads";
Animal a(AnimalType);
I suggest this because I've worked places where the conditional operator was forbidden. (Sigh!) Also, this can be expanded beyond two alternatives very easily.
If you want to avoid garbage collection - you could use a smart pointer.
auto_ptr<Animal> p_a;
if ( happyDay() )
p_a.reset(new Animal( "puppies" ) );
else
p_a.reset(new Animal( "toads" ) );
// do stuff with p_a-> whatever. When p_a goes out of scope, it's deleted.
If you still want to use the . syntax instead of ->, you can do this after the code above:
Animal& a = *p_a;
// do stuff with a. whatever
In addition to Greg Hewgill's answer, there are a few other options:
Lift out the main body of the code into a function:
void body(Animal & a) {
...
}
if( happyDay() ) {
Animal a("puppies");
body( a );
} else {
Animal a("toad");
body( a );
}
(Ab)Use placement new:
struct AnimalDtor {
void *m_a;
AnimalDtor(void *a) : m_a(a) {}
~AnimalDtor() { static_cast<Animal*>(m_a)->~Animal(); }
};
char animal_buf[sizeof(Animal)]; // still stack allocated
if( happyDay() )
new (animal_buf) Animal("puppies");
else
new (animal_buf) Animal("toad");
AnimalDtor dtor(animal_buf); // make sure the dtor still gets called
Animal & a(*static_cast<Animal*>(static_cast<void*>(animal_buf));
... // carry on
Since c++17, there is now an overhead-free way to do this: std::optional. The code in this case would be:
#include <optional>
std::optional<Animal> a;
if (happyDay()) {
a.emplace("puppies");
} else {
a.emplace("toads");
}
The best work around is to use pointer.
Animal a*;
if( happyDay() )
a = new Animal( "puppies" ); //constructor call
else
a = new Animal( "toads" );
You can also use std::move:
class Ball {
private:
// This is initialized, but not as needed
sf::Sprite ball;
public:
Ball() {
texture.loadFromFile("ball.png");
// This is a local object, not the same as the class member.
sf::Sprite ball2(texture);
// move it
this->ball=std::move(ball2);
}
...
There is a way to do this without pointers/heap memory, this syntax is just a bit gibberish. Here is an example using std::string. I don't recommend doing this unless you really need the performance.
uint8_t object[sizeof(std::string)];
int main() {
if(true)
new(&object) std::string("Your arguments");
else
new(&object) std::string("Your other arguments");
(*(std::string*)(&object)).append("");
std::cout << (*(std::string*)(&object));
return 0;
}
The annoying part about this is you have to cast object to a string every time you want to use it:
(*(std::string*)(&object))
Yes, you can do do the following:
Animal a;
if( happyDay() )
a = Animal( "puppies" );
else
a = Animal( "toads" );
That will call the constructors properly.
EDIT: Forgot one thing...
When declaring a, you'll have to call a constructor still, whether it be a constructor that does nothing, or still initializes the values to whatever. This method therefore creates two objects, one at initialization and the one inside the if statement.
A better way would be to create an init() function of the class, such as:
Animal a;
if( happyDay() )
a.init( "puppies" );
else
a.init( "toads" );
This way would be more efficient.