I have used function objects to find out what happens to the object that gets passed, and how it effects the state of the object. Here is a snippet of the test code:
#include <iostream>
//#include <boost/function.hpp>
//using boost::function;
#include <functional>
using std::function;
using std::bind;
struct A {
A() { std::cout << "Creating..." << "\n"; }
void operator()() { call(); }
void call() { std::cout << "Executing call..." << "\n"; }
virtual ~A() { std::cout << "Destroying" << "\n"; }
};
typedef function<void ()> Func;
struct B{
Func f;
B(Func ff) : f(ff) {}
void call() {f();}
};
int main(int argc, char *argv[])
{
{
A a;
B b(a);
for (int i = 0; i < 5; ++i)
b.call();
}
{
A a2;
B b2(bind(&A::call, &a2));
for (int i = 0; i < 5; ++i)
b2.call();
}
return 0;
}
/** Output **
Creating...
Destroying
Destroying
Executing call...
Executing call...
Executing call...
Executing call...
Executing call...
Destroying
Destroying
Creating...
Executing call...
Executing call...
Executing call...
Executing call...
Executing call...
Destroying
*/
When I pass the object with operator () overloaded, there is some multiple calls to destructors; and no objects are being created! So, I can not rely, so to say, on the fidelity of the object state. Does it mean that when I pass a function object (with overloaded operator()) for callback, I should assume that the state of the object is not preserved? And is this, the intended behavior?
On the other hand, callback to a bound member function from inside of an object of another type produces a very stable behavior (I don't know what term to use); i.e. to say, I expected the object state to be preserved; and indeed it is! Is this also an intended behaviour? IOW, is this how functors are generally understood?
PS:
I also checked it with boost::function and boost::bind --- The result is quite the similar. Probably another thread is required to discuss the nuances.
About "no constructors": There are calls to the copy constructor.
Try more instrumenting:
struct A {
A() { std::cout << "Creating..." << "\n"; }
void operator()() { call(); }
A(const A&) { std::cout << "Copying" << "\n"; }
A(A&&) { std::cout << "Moving" << "\n"; } // Assuming C++11
void call() { std::cout << "Executing call..." << "\n"; }
virtual ~A() { std::cout << "Destroying" << "\n"; }
};
About copying:
You hand over the callable by value to B's constructor. It has to be copied.
Bind, it is the intended behavior if you hand in a value. The callable you're handing to bind might be a temporary. Thus, the default behavior is to copy.
You can avoid this, by using a reference wrapper, if you know your callable will survive long enough (as is the case in your code). Try:
int main(int argc, char *argv[])
{
{
A a;
{
B b(a);
}
std::cout << "-------------\n";
B(std::ref(a));
std::cout << "-------------\n";
B(bind(&A::call, a));
std::cout << "-------------\n";
B(bind(&A::call, &a));
std::cout << "-------------\n";
B(bind(&A::call, std::ref(a)));
std::cout << "-------------\n";
}
std::cout << "-------------\n";
return 0;
}
When I pass the object with operator () overloaded, there is some multiple calls to destructors; and no objects are being created!
You are not counting the objects that are constructed using the copy constructor, which is created by the compiler when you don't provide any.
Add a copy constructor to A and you will see the number of calls to the destructor to be the same as the calls to the constructors.
struct A {
A() { std::cout << "Creating..." << "\n"; }
// Add this
A(A const& copy) { std::cout << "Creating..." << "\n"; }
void operator()() { call(); }
void call() { std::cout << "Executing call..." << "\n"; }
virtual ~A() { std::cout << "Destroying" << "\n"; }
};
Related
sorry but I cant understand why 2 times destructor called?
#include <iostream>
#include <thread>
class myClass
{
public:
int integer;
void operator()()
{
std::cout << "class: " << integer << "\t" << std::this_thread::get_id() << std::endl;
}
myClass(int h)
: integer{h}
{
}
~myClass()
{
std::cout << "MyClass by int: " << integer << " destroyed!" << std::endl;
}
};
bool myFunc(int x)
{
myClass tempClass(x);
std::thread one(tempClass);
one.join();
if (x <= 0)
return 0;
else
return myFunc(x - 1);
}
int main()
{
myFunc(10);
return 0;
}
note : I'm just trying in MultiThreads. (training)
and one more problem is that why before joining thread , my class has destroyed!
In the line
std::thread one(tempClass);
a copy of tempClass is created. Later on, both instances of myClass are destroyed.
You can pass tempClass by reference by using std::ref, but then you have to guarantee that tempClass remains valid (e.g. does not go out of scope, is brought in an invalid state by the main thread) throughout the life time of your thread (one).
You can also move tempClass into the other thread. You would still end up with two destructor calls and it would hardly make any difference in your case, but if myClass is difficult to copy, it can make a difference. In that case, you may want to read up on move semantics.
I don't understand why the '''execute''' function of the Parent class is run. I feel like there are two instances: one for the parent class, one for the child class, but why? Indeed, this program is printing "1 Parent", as i expected "1 Child" or "0 Parent". If i uncomment the delay line, the output will be "1 Child".
I know there is a race condition in this program. This program was only made to understand the working principle of the inheritance in a multithreaded environment.
Thank you !
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <thread>
class Parent
{
public:
std::thread myThread;
int a;
Parent() {
this->myThread = std::thread();
this->a = 0;
}
void start()
{
this->myThread = std::thread(&Parent::execute, this);
}
virtual void execute() {
std::cout << a << " Parent" << std::endl;
}
virtual ~Parent() {
while(!this->myThread.joinable());
this->myThread.join();
}
};
class Child : public Parent
{
public:
Child() {
this->a = 1;
}
void execute() override {
std::cout << a << " Child" << std::endl;
}
~Child() {
}
};
int main()
{
std::cout << "Init" << std::endl;
Child * chld = new Child();
chld->start();
//std::this_thread::sleep_for(std::chrono::milliseconds(x));
std::cout << "Delete" << std::endl;
delete chld;
return 0;
}
Your program has undefined behavior which means "everything can happen".
You start a new thread which hold a pointer ( this ) to an object. This thread will later call a virtual method which means it needs to use data from the object it points to. The vtable pointer itself is some kind of data of the class. Because you delete your object from the other thread, the pointer ( this ) is simply pointing to a destructed object and accessing data ( vtable ) from an deleted object is undefined behavior.
Your observation is depending on the compiler implementation and maybe also on optimizing level. It is possible, that your compiler rewinds during deconstruction the vtable pointer down to the base class pointer. And as the memory of the object is not overridden from any other content ( which is even undefined! ) you can observe a call to the base function after destruction. But this is nothing you can rely on, as it is not allowed at all to use any object after destruction IF you use data members of the object which here is the vtable pointer.
In a short: Your code contains a bug and everything can happen as it is undefined behavior.
Your code exhibits the Undefined behavior (in your case resulting in Parent::execute call) because of the race condition between thread creation and Child object destruction. To fix it, you can define proper start and stop methods in your Parent class and call stop in Child destructor to prevent it from being destroyed before thread joins.
class Parent
{
public:
Parent(): myThread_() {
std::cout << "Parent CTor" << std::endl;
}
virtual ~Parent() = default;
bool start()
{
std::cout << "start" << std::endl;
if (myThread_.joinable()) {
std::cout << "already started" << std::endl;
return false;
}
myThread_ = std::thread([this]() {
execute();
});
return true;
}
bool stop() {
std::cout << "stop" << std::endl;
if (!myThread_.joinable()) {
std::cout << "not started" << std::endl;
return false;
}
myThread_.join();
return true;
}
virtual void execute() = 0;
private:
std::thread myThread_;
};
class Child : public Parent
{
public:
Child() {
std::cout << "Child CTor" << std::endl;
}
~Child() override {
stop();
}
void execute() override {
std::cout << "Child::execute()" << std::endl;
}
};
int main()
{
std::cout << "Init" << std::endl;
Child * chld = new Child();
chld->start();
std::cout << "Delete" << std::endl;
delete chld;
return 0;
}
I defined Parent::execute as abstract because probably you don't want it to be called at all and in case of another bug, at least you can get
terminate, pure virtual method called
This is nothing whatsoever to do with threads. You can reproduce the whole thing - including Undefined Behaviour - synchronously.
Single-threaded version of your classes:
#include <iostream>
#include <string>
class Parent
{
public:
int a;
Parent() : a(0) {}
virtual ~Parent() {}
virtual void execute() {
std::cout << a << " Parent" << std::endl;
}
};
class Child : public Parent
{
public:
Child() {
a = 1;
}
void execute() override {
std::cout << a << " Child" << std::endl;
}
};
and the single-threaded test cases demonstrating exactly the same behaviour:
int main()
{
Child c;
std::cout << "=== automatic lifetime ===\n";
std::cout << "virtual dispatch: ";
c.execute();
std::cout << "explicit static dispatch: ";
c.Parent::execute();
std::cout << "=== dynamic lifetime ===\n";
Child *pc = new Child;
std::cout << "virtual dispatch: ";
pc->execute();
std::cout << "explicit static dispatch: ";
pc->Parent::execute();
std::cout << "=== undefined behaviour ===\n";
delete pc;
std::cout << "explicit static dispatch: ";
pc->Parent::execute();
std::cout << "virtual dispatch: ";
pc->execute();
}
The last two output statements are swapped, because the last one crashed when I ran it (the penultimate is still UB, but happened not to crash)
=== automatic lifetime ===
virtual dispatch: 1 Child
explicit static dispatch: 1 Parent
=== dynamic lifetime ===
virtual dispatch: 1 Child
explicit static dispatch: 1 Parent
=== undefined behaviour ===
explicit static dispatch: 1 Parent
Segmentation fault (core dumped) ./a.out
I am passing unique_ptr to function and then move the pointer to another unique_ptr, all is working fine as need, but while point is unique_ptr does not call destructor of the when it goes out of scope.
Below is my code. and its output, the code is in eclipse.
#include <iostream>
#include <memory>
using namespace std;
class BaseCcExpander;
class DeriveHandler;
class ExpansionRuleExecuter;
class DeriveType1;
class ParamBase
{
public :
ParamBase()
{
std::cout << "Ctor:ParamBase:\n";
}
std::unique_ptr<ExpansionRuleExecuter> paramexpander;
virtual ~ParamBase() { std::cout << "Dtor::~ParamBase:\n"; }
virtual void attachBase(int paramGrp,int paramId,std::unique_ptr<ExpansionRuleExecuter> xbaseExpander);
};
ParamBase* obj;
void ParamBase::attachBase(int paramGrp,int paramId,std::unique_ptr<ExpansionRuleExecuter> xbaseExpander)
{
std::cout << "In: ParamBase::attachHandler :\n";
paramexpander = std::move(xbaseExpander);
}
class ExpansionRuleExecuter
{
public:
ExpansionRuleExecuter()
{
std::cout << "Ctor ExpansionRuleExecuter::ExpansionRuleExecuter:\n" << endl;
}
virtual ~ExpansionRuleExecuter(){
std::cout << "Dtor ~ExpansionRuleExecuter::ExpansionRuleExecuter:\n" << endl;
}
virtual void handleExpansion() = 0;
};
class DeriveHandler : public ExpansionRuleExecuter
{
public:
DeriveHandler()
{
std::cout << "Ctor::DeriveHandler:\n" << endl;
}
~DeriveHandler()
{
std::cout << "Dtor::~DeriveHandler:\n" << endl;
}
void handleExpansion()
{
std::cout << "DeriveHandler expanded\n" << endl;
}
};
ParamBase *obj1;
class BaseCcExpander
{
public:
BaseCcExpander()
{
std::cout << "Ctor::BaseCcExpander:\n" << endl;
}
virtual ~BaseCcExpander()
{
std::cout << "Dtor::~BaseCcExpander:\n" << endl;
}
typedef unique_ptr<ExpansionRuleExecuter> ccHandler;
BaseCcExpander::ccHandler ccBaseHandler;
void attachHandler(int paramGrp, int paramId,std::unique_ptr<ExpansionRuleExecuter> xhandler)
{
std::cout << "BaseCcExpander::attachHandler:\n" << endl;
obj1->attachBase(paramGrp,paramId,std::move(xhandler));
}
};
class DeriveType1 : public ParamBase
{
public :
DeriveType1() { std::cout << "Ctor: DeriveType--------1:\n" << endl;}
~DeriveType1() { std::cout << "Dtor::~DeriveType---------1\n" << endl;}
void attachBase(std::unique_ptr<ExpansionRuleExecuter> xbaseExpander);
};
BaseCcExpander ccexpander;
int main()
{
obj1 = new(DeriveType1);
ccexpander.attachHandler(1,2,std::unique_ptr<ExpansionRuleExecuter>(new DeriveHandler));
if(obj1->paramexpander.get())
{
ExpansionRuleExecuter *expand = obj1->paramexpander.get();
expand->handleExpansion();
}
}
You wrote in a comment:
but by is obj1 not destroying even after the program is over as its in the global space, it should destroy.
There is some misunderstanding here. obj1 is destroyed but the object it points to is not deleted when obj1 is destroyed. If the compiler did that, you won't be able to use:
int main()
{
int i = 10;
int* ip = &i;
// You don't want the run time to call the equivalent of
// delete ip;
// when the function returns. That will lead to undefined behavior
// since ip does not point to memory allocated from the heap.
}
When the program ends, the OS reclaims the memory used by the program but that does not mean that it calls the destructor of obj1.
Had the destructor been responsible for releasing resources other than memory, such as network connections, locks on shared files/folders, etc., they will not be released when the program ends without the destructor getting called.
Your variable pointed by obj1 is not deleted, hence its members would not be destroyed until the delete happens and the unique_ptr will remain alive then the destructor will never be called.
You should either call delete on obj1 at the end of your program or use an unique_ptr on it.
In my project, there are two components: producer and consumer. Producer is responsible for processing some information and giving the result to consumer. The result is passed with help of function object.
I am using a function for passing this information. You could see how it could look in the code below.
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
class Data {
std::vector<int> vec;
public:
Data() {
cout << "Data()" << endl;
}
Data(const Data& rr) : vec(rr.vec) {
cout << "Data(Data&)" << endl;
}
~Data() {
cout << "~Data()" << endl;
}
Data(Data&& rr) : vec(move(rr.vec)) {
cout << "Data(Data&&)" << endl;
}
void get() {
}
};
class Producer {
public:
void process(function<void(Data)> f) {
Data data;
f(move(data));
}
void process2(void(&pf)(Data)) {
Data c;
pf(move(c));
}
};
void Consume(Data a) {
cout << "Consume(data)" << endl;
}
int main() {
{
cout << "use function() " << endl;
Producer p;
p.process([](Data a) {
cout << "Consume(data)" << endl;
});
}
{
cout << endl;
cout << "use function pointer" << endl;
Producer p;;
p.process2(Consume);
}
return 0;
}
it has the following output
use function()
Data()
Data(Data&&)
Data(Data&)
Data(Data&)
Consume(data)
~Data()
~Data()
~Data()
~Data()
use function pointer
Data()
Data(Data&&)
Consume(data)
~Data()
~Data()
There are additional copy constructors when function object is used.
Did I do something wrong? Is it possible to get rid of these extra constructors?
Thank you in advance.
I am using VC10 SP1.
You have a few options here.
Don't use std::function, your non-capturing lambda is convertible to void(*)(Data)
Don't use std::function, make your functions templates, the compiler can deduce the hidden type of the lambda.
Don't copy objects, pass them around as pointers or references. Depending on what the full version of the program is doing, it may be more efficient to allocate on the heap and use std::unique_ptr.
This is related to a question posted yesterday.
class A
{
public:
mutable int x;
A()
{
static int i = 0;
x = i;
i++;
std::cout << " A()" << std::endl;
}
~A()
{
std::cout << "~A()" << std::endl;
}
void foo() const
{
x = 1;
};
};
class B
{
public:
const A & a;
B(const A & a) : a(a)
{
std::cout << " B()" << std::endl;
}
~B()
{
std::cout << "~B()" << std::endl;
}
void doSomething()
{
a.foo();
};
};
int main()
{
B b((A()));
b.doSomething();
}
Now, a's destructor is called before the call to doSomething. However, the call works although the function basically changes a member of A. Is it not the same instance. No other A's are created. I used the static inside A's constructor to keep track of that. Can anyone explain?
This is undefined behavior, so there is no language standard explanation.
However, the destructor of A doesn't do anything to the memory area where x is stored, so if you look there later the value might just still be there. Or if you try to write to the address, the address is still there. You are just not allowed to do that.
Bo is correct.
In addition, you could check the address where 'A' is stored, and that should confirm that that address simply hasn't been reused yet (keep in mind a destructor frees ("releases") the memory, but doesn't traverse the data structure setting all of the bits back to 0; that would be inefficient).
If, for example, you find that A is stored on top of the stack, then you are simply fortunate that your subsequent function call doesn't pass in a parameter, as that would overwrite A's memory region.
Your reference is invalid after ~A() and it is undefined behavior
~A() calls destructors of all members of A in addition
Try so for example
class B
{
public:
const std::string & a;
B(const std::string & a) : a(a)
{
std::cout << " B()" << std::endl;
}
~B()
{
std::cout << "~B()" << std::endl;
}
void doSomething()
{
std::cout << "a = " << a << std::endl;
};
};
int main()
{
B b(std::string("I love C++ so much!"));
b.doSomething();
}
Expanding on Bo's answer.
For a temporary to exist, space will be reserved on the stack. This space is actually reserved as long as the semantics require the temporary to exist, and may then be reuse for something else.
If you were trying to use the memory after it has been reused, you would observe a strange behavior (the very definition of undefined behavior being that anything can happen). As it is, you luck out and the memory is still there, in the state you expect it to.
Example:
#include <iostream>
struct A {
A(): p(0) {}
~A() { if (p) { std::cout << *p << "\n"; } }
int* p;
};
int bar0();
void bar1(int i);
int main() {
A a;
{
int x = 4; a.p = &x;
}
{
int y = bar0(); bar1(y);
}
}
int bar0() { return 7; }
void bar1(int i) { std::cout << i << "\n"; }
Here, the compiler may choose to reuse the space of x for y, or just do anything it wants, and thus you're actually printing garbage.
Here is gcc 4.3.4 (and 4.5.1) output (courtesy of ideone):
7
4
Meaning that the space is not reused with those...