Here is the code, it's pretty straightforward.
class Foo
{
public:
void print()
{
std::cout<<"Foo::print\n";
}
};
Game::Game()
{
{
Foo foo;
player.onclick = bind(&Foo::print,foo);
}
player.onclick();
}
After the inner scope is done the foo object goes out of scope, but the print method is still called, I guess this happens because player holds a reference to the foo object? Is there a way to stop this from happening? I don't want objects to stay alive and receive events when they are supposed to be destroyed.
Thanks.
You are binding to a copy of foo; that copy lasts as long as the bound function object, while the original foo is destroyed at the end of its scope.
If you don't want to keep it alive, then bind to a pointer (&foo) or a reference (std::ref(foo)); and then you must be careful not to call the function object once foo has gone out of scope. Note that there's no way to tell from the function object that this has happened; calling it will give undefined behaviour.
In order to safely disconnect the object when it's destroyed, you would have to either arrange for its destructor to reassign onclick, or make some other object responsible for first reassigning onclick, and then destroying the object.
From your description it sounds like you actually want an event loop. While std::bind is useful for something like that it isn't one all by itself. I suggest you have a look at boost.signals
I think you should use shared_ptr when you assign Foo to Player, and keep a weak_ptr to Foo in Player. Then try to lock the weak_ptr in the onclick function to see if Foo is still alive. Something like this:
using namespace std;
class Foo
{
public:
void print()
{
cout<<"Foo::print\n";
}
};
class Player
{
public:
weak_ptr<function<void()>> _onClickFuntion;
void onclick()
{
shared_ptr<function<void()>> tempFunction(_onClickFunction.lock());
if (tempFunction)
tempFunction();
}
}
Game::Game()
{
{
Foo foo;
player._onClickFuntion = shared_ptr<function<void()>>(new bind(&Foo::print,foo));
}
player.onclick();
}
Related
I am trying to create and use a std::shared_ptr within a class function whose constructor takes in a std::shared_ptr private data member (of the same class) and another std::shared_ptr created with a raw pointer to the class object (this).
Whenever I call the function that creates the std::shared_ptr (foo), I get a _CrtIsValidHeapPointer(block) assertion. I'm assuming it has something to do with the way in which the shared_ptr is being deleted, but I can't seem to figure it out, and I've searched all over the Internet. Maybe I'm not fully understanding how shared_ptrs work.
Is it not acceptable to create a shared_ptr using the this pointer, or a pre-existing shared_ptr data member?
class Containing_Class;
class Some_Class
{
};
class Set_Value_Command
{
public:
Set_Value_Command(std::shared_ptr<Some_Class> ptr1, std::shared_ptr<Containing_Class> ptr2)
: _ptr1(ptr1), _ptr2(ptr2)
{}
private:
std::shared_ptr<Some_Class> _ptr1;
std::shared_ptr<Containing_Class> _ptr2;
};
class Containing_Class
{
public:
Containing_Class(std::shared_ptr<Some_Class> psc)
: _psc(psc)
{}
void foo()
{
std::shared_ptr<Set_Value_Command> command = std::make_shared<Set_Value_Command>(_psc, std::shared_ptr<Containing_Class>(this));
}
private:
std::shared_ptr<Some_Class> _psc;
};
Here is the main() function. When foo() is called, the assertion happens:
int main()
{
std::shared_ptr<Some_Class> some_class = std::make_shared<Some_Class>();
Containing_Class cc(some_class);
cc.foo();
}
Is it not acceptable to create a shared_ptr using the this pointer
Not by itself, no. And doing so in your example is very bad. Your Containing_Class object is being created in automatic memory of main()'s local stack frame, and thus will be destroyed automatically when it goes out of scope when main() exits. But creating a shared_ptr from this inside of the Containing_Class object will assign ownership of this to the shared_ptr, which will then try to delete this when there are no more shared_ptr references to this. delete'ing an object that was not created with new to begin with is undefined behavior, and is why you are crashing with an error about an invalid heap pointer.
In order to allow shared_ptr to refer to this, Containing_Class would need to derive from std::enable_shared_from_this, and this would have to point at an object that is created dynamically and owned by a shared_ptr. Only then can Containing_Class call its inherited shared_from_this() method to get a shared_ptr to itself.
For example:
class Containing_Class;
class Some_Class
{
};
class Set_Value_Command
{
public:
Set_Value_Command(std::shared_ptr<Some_Class> ptr1, std::shared_ptr<Containing_Class> ptr2)
: _ptr1(ptr1), _ptr2(ptr2)
{}
private:
std::shared_ptr<Some_Class> _ptr1;
std::shared_ptr<Containing_Class> _ptr2;
};
class Containing_Class : public std::enable_shared_from_this<Containing_Class>
{
public:
Containing_Class(std::shared_ptr<Some_Class> psc)
: _psc(psc)
{}
void foo()
{
std::shared_ptr<Set_Value_Command> command = std::make_shared<Set_Value_Command>(_psc, shared_from_this());
}
private:
std::shared_ptr<Some_Class> _psc;
};
int main()
{
auto some_class = std::make_shared<Some_Class>();
auto cc = std::make_shared<Containing_Class>(some_class);
cc->foo();
}
With the code
std::shared_ptr<Containing_Class>(this)
you introduce a second *this owner, i.e. command is the owner of a shared pointer that controls cc life. That is the first issue. Yet another, following issue is that command is pointing to a stack object.
Usually *this is owned by someone and passing ownership to another owner never works.
The current code is impossible to fix due to lack of the code aim.
I have to call a function of a class from another function of the same class. But the problem is for some cases the current object can be destroyed. So for this case calling the function is creating errors. Is there any way to check whether the current object is destroyed or not from inside the class?
Another thread may first delete the current object and then create another object of the same class before calling function1 from inside function2. In that case, calling function1 would be valid, right?
For example,
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
class example {
public:
example(){}
~example() {}
void function1() {
// some code here
return;
}
void function2() {
//some code here
// I want to check whether the current object is destroyed or not before calling function1()
function1();
}
private:
bool check;
};
int main()
{
example *exp=new example();
exp->function2();
}
Is there any way to check whether the current object is destroyed or not from inside the class?
No, there is no way to do that.
I presume that "from inside the class" means "by using state of the object". Well, if the object is destroyed, then there is no state that could be observed. Any attempt would result in undefined behaviour.
Also, when the object has been destroyed, member functions of the object may not be called, so it is pointless to test that in function2 because if the object had been destroyed, then calling function2 would already result in undefined behaviour.
extern class objx;
class Someclass
{
public:
Someclass();
void bar(objx);
objx &om;
};
void foo()
{
Someclass c;
objx o;
c.bar(o);
}
void Someclass::bar(objx& op)
{
//Save op in some local privatefield for later use
om = op; //Here there should not be a copy;
}
Above code is wrong right? Because when o goes out of scope in foo() it is destructed. Is there a way not to copy o into a new object in bar? For example using bar(objx&& op) so we don't have to copy object or use smart pointers and for sure avoiding new/delete? And when bar() returns op would go out of scope and object gets destroyed.
[EDIT]
I could use a pointer instead. But the caller should keep track of the lifetime of the object. That is what I want to avoid.
[EDIT2]
The question is this: Is there a mechanism to keep a local variable alive as long as its reference is passed by reference to other functions (scopes)?
[EDIT4]
This code achieves same functionality using pointers:
#include <sstream>
class Someclass
{
public:
Someclass() { }
void bar(std::stringstream *);
std::stringstream *om;
};
void Someclass::bar(std::stringstream* op)
{
om = op;
}
int main()
{
Someclass c;
std::stringstream o;
c.bar(&o);
return 0;
}
Above code is wrong right? Because when o goes out of scope in foo() it is destructed.
It depends on what "Save op in some local privatefield for later use" means. Making a copy is correct. Referring to the object would not be.
Is there a way not to copy o into a new object in bar?
You can move into a new object instead.
The receiver class is already instantiated.
Option 1: Don't do that.
Option 2: Assign the value member.
From the responses you kindly provided I concluded that it can be done if the passing object has the move semantics implemented in it.
sf::RectangleShape* operator()()
{
return &player;
} // RectangleShape Getter
Do I need to free memory after this getter? If yes, how would one do this with unique_ptr?
I tried
std::unique_ptr<sf::RectangleShape> operator()()
{
return std::unique_ptr<sf::RectangleShape>(player);
} // RectangleShape Getter
But it says there is no matching function for the parenthesis operator. How else should this be done?
sf::RectangleShape* operator()()
{
return &player;
} // RectangleShape Getter
Do I need to free memory after this getter?
All you do is return a pointer to player. Assuming that is a member variable of the struct/class the above member function is a part of, then its lifetime is bound to the lifetime of the object you call that function with.
In particular that means that this is a bad idea:
struct Foo {
sf::RectangleShape player;
// ...
// insert your operator here
};
sf::RectangleShape * some_function(void) {
Foo f;
return f(); // UB, returning pointer to object with automatic memory whose lifetime has ended
}
[..] how would one do this with unique_ptr?
Assuming sf::RectangleShape has a copy constructor, then you could make a copy of player:
std::unique_ptr<sf::RectangleShape> operator()() {
return make_unique<sf::RectangleShape>(player);
}
The copy you get that way is "yours", i.e. you can manage is lifetime as you want.
It seems like player is member of a class and you are trying to hand out a pointer to it for it to modified outside the class?
In this case, the class it belongs to owns the memory and it is down to that class to handle freeing the data when it is destroyed. A pointer to that member should absolutely not be freed from outside the class.
It would help to have more information about the owning class, but if I can assume that player is a data member, then your first example is technically fine. However it is often more idiomatic to return a reference than pointer.
class SomeClass
{
sf::RectangleShape player;
sf::RectangleShape& operator()()
{
return player;
}
};
If the above assumption is incorrect, you should show your full class definition so we have more information to form a correct solution.
I know this is very silly question about singleton pattern but still it is first choice of interviewer.
Could you let me know in below code snippet.
(1) After deleting singleton object why still I am able to call show() method and it works fine.
delete obj;
obj=NULL;
obj->show();
(2) After creating obj1 object why i am not able to print the content of acquire_lock and release_lock function even print statment "one Time" will be printed once and if we increment counter i then instead of 2 it is printing 1 only, why?
Foo *obj1=MySingleton<Foo>::GetInstance();
(3) usage of unique_ptr with singleton object will have any negative implications.
code snippet:
#include <iostream>
#include <fstream>
#include <memory>
#include <string>
using namespace std;
static int i;
class Lock
{
public:
Lock(){};
~Lock(){};
void acquire_lock()
{
cout<<"aquired lock for class";
}
void release_lock()
{
cout<<"released lock for class";
}
};
class Foo
{
public:
void show()
{
cout<<"\ndone\n";
}
};
template <class T>
class MySingleton
{
protected:
MySingleton() {}
private:
//holds one and only object of MySingleton
static T* m_pOnlyOneInstance;
MySingleton(const MySingleton <T> &) {};
MySingleton <T> & operator=(const MySingleton <T> &) {};
~MySingleton() {};
public:
static T * GetInstance();
void foo()
{
cout<<"Mohan";
}
};
template <class T>
T* MySingleton<T>::GetInstance()
{
Lock lock;
if (m_pOnlyOneInstance == NULL)
{
lock.acquire_lock();
cout<<"one Time"<<endl;
i++;
if(m_pOnlyOneInstance == NULL)
{
m_pOnlyOneInstance = new T();
}
lock.release_lock();
}
return m_pOnlyOneInstance;
}
template <class T> T* MySingleton<T> :: m_pOnlyOneInstance=NULL;
int main()
{
//std::unique_ptr <Foo> obj (MySingleton<Foo>::GetInstance());
Foo *obj=MySingleton<Foo>::GetInstance();
//obj->show();
delete obj;
obj=NULL;
obj->show();
cout<<"\ncalling again\n";
Foo *obj1=MySingleton<Foo>::GetInstance();
obj1->show();
cout<<"i="<<i;
return 1;
}
Note: lock related function are dummy implementation only.
Keep in mind that obj->show() is equivalent to Foo::show(obj). Both expressions set this to the value of obj within the show member function. Now, what would setting this to NULL within show do? Nothing, because you never reference this.
Well, think about the whole reason you would use the singleton pattern in the first place -- to initialize something at most one time. That "one time" print statement is in the code where the object gets instantiated, so naturally it doesn't get executed after the first time. Look at the logic of GetInstance. If an instance does not exist, it instantiates the class (messily... but it does work), and afterwards the instance exists. Otherwise, it does nothing.
This question is very unclear, but what I assume you mean is "what are the negative implications of doing std::unique_ptr<Foo> obj = MySingleton<Foo>::GetInstance();?" As you can see from the reference for unique_ptr, its purpose is to take ownership of a dynamically allocated resource. This is definitely not supposed to happen when you're dealing with singleton objects. Because the resource (the singleton instance, in this case) is shared among any number of callers, the singleton class is the only one which should be managing the instance resource -- this is a fundamental invariant of the singleton pattern. If you use unique_ptr, as soon as obj goes out of scope, it will delete the instance automatically, regardless of whether your program references the now-freed instance elsewhere.
This is not a proper way to delete the singleton object, you need to write below method in order to delete the instance and then execute your programme.
static void cleanup()
{
delete m_pOnlyOneInstance;
m_pOnlyOneInstance= NULL;
}
Here is the output :
aquired lock for classone Time
released lock for class
done
calling again
aquired lock for classone Time
released lock for class
done
i=2
(1)
The call would fail if it actually used obj either to perform the call or within the call.
First the call it self is to a non virtual function so the obj pointer is not needed to find the function. The compiler already figured out at compile time which function to call.
Second the function does not access any member variables of the class so while it does receive a this pointer that is NULL it actually never uses it.
BTW, it seems that this code tries to use the MySingleton template to turn other classes into singletons but it doesn't really as it doesn't prevent making copies or instantiating objects through other ways so it is no true singleton. The only thing it does is always return the same pointer.
Other BTW, the second call to MySingleton<Foo>::GetInstance() returns a copy of a pointer that you have previously deleted when you did delete obj. obj was set to NULL after the delete but the original pointer in the MySingleton template is still pointing to the deleted object so the second call to GetInstance will happily return the now invalid pointer.
Your singleton class should have a private constructor and destructor. The destructor should handle any memory cleanup when the scope of the singleton ends, so there's no need to explicitly delete it. It could be unsafe to delete it when other objects are still accessing the singleton after the point of deletion. You could be getting an undefined behavior when you did "delete obj", and "obj=null" since you overloaded assignment operator and destructor are private.