I have some class A
, which I can either construct using nothing, or an std::function
. On destruction that given function should be called (in case there is one). My problem is that the object gets destroyed right after it is created and returned by my getSomeA()
function which calls the std::function
before it is supposed to be called. The function passed to the constructor should only be called once. Some example code:
#include <iostream>
#include <functional>
static void testFunction(const std::string& msg)
{
std::cout << "TestFunction: " << msg << "\n";
}
class A {
public:
A(void) = default;
A(const std::function<void()>& onDestroy) :
onDestroy(onDestroy)
{ }
~A(void)
{
if (onDestroy) onDestroy();
else std::cout << "in dtor but no onDestroy was set\n";
}
private:
std::function<void()> onDestroy;
};
A getSomeA(void)
{
return A(std::bind(testFunction, "the A that was created inside getSomeA"));
}
int main(void)
{
A b1;
std::cout << "After creating b1\n";
b1 = getSomeA();
std::cout << "After reassigning b1\n";
std::cout << "Here the program works with b1...\n";
}
The program outputs
After creating b1
TestFunction: the A that was created inside getSomeA
After reassigning b1
Here the program works with b1...
TestFunction: the A that was created inside getSomeA
So the function is called before it is supposed to be called (at the end of int main()).
After adding a move constructor and assignment operator everything works as expected:
A(A&& other) :
onDestroy(std::exchange(other.onDestroy, nullptr))
{ }
A& operator=(A&& other)
{
onDestroy = std::exchange(other.onDestroy, nullptr);
return *this;
}
And the program outputs
After creating b1
in dtor but no onDestroy was set
After reassigning b1
Here the program works with b1...
TestFunction: the A that was created inside getSomeA
The actual question: Where is the object destroyed for the first time so that testFunction is called? In getSomeA()
or in the main function before the assignment but after the object was created in getSomeA()
?
All the edits: I tried to bring down my question for one hour but since I have no idea about move/copy semantics in C++ that was pretty hard for me.