Extra copy constructors when std::function is used - c++

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.

Related

How to call a C++ class method, which is given as a parameter?

I'm trying to pass a method as a parameter to other method.
Magner.h:
Class Manager{
public:
timeCount(void (Manger::*function)(void));
void passedFuction();
}
In Manager.cpp, I'm trying to call timeCount by
timeCount(&Manager::passedFuction());
TimeCount Body:
void Manager::timeCount(void(Manager::*function)(void))
{
std::cout << "It works";
(*function)(); // here is error
}
ViusalStudio says:
void*Manager::*function)() operand of '*' must be a pointer
How should i correct it?
The example i was learing by was : http://www.cplusplus.com/forum/beginner/6596/
A pointer-to-member-function (pmf) is not a pointer. Let me repeat that:
A pointer-to-member-function is not a pointer.
To call a pmf, you have to provide it with the object you want to call it on. You probably want:
(this->*function)();
If you had another object obj of the right type, you could also use:
(obj.*function)();
The void (Manger::*function)(void) syntax is for member functions of Manager class, which cannot be used with functions outside the Manager class.
To fix this shortcoming, pass std::function<void(void)> instead, which would let you invoke itself using the regular function invocation syntax:
void Manager::timeCount(std::function<void(void)> f) {
std::cout << "It works";
f();
}
Here is a complete demo of how to call timeCount with member and non-member functions:
struct Manager {
string name;
void timeCount(std::function<void(void)> f) {
std::cout << "This is " << name << " manager" << endl;
f();
}
};
void foo() {
cout << "I'm foo" << endl;
}
struct Test {
int x;
void bar() {
cout << "I'm bar " << x << endl;
}
};
int main() {
Manager mgr {"time"};
mgr.timeCount(foo);
Test tst = {234};
mgr.timeCount(std::bind( &Test::bar, tst));
return 0;
}
Demo.
Since c++17, we have std::invoke:
std::invoke(function, this);
or
std::invoke(function, *this);
are both ok. Minimal demo:
#include <functional>
#include <iostream>
class Manager
{
public:
void timeCount(void (Manager::*function)(void));
void passedFuction()
{
std::cout << "call passedFunction\n";
}
};
void Manager::timeCount(void (Manager::*function)(void))
{
std::cout << "It works\n";
std::invoke(function, *this);
// (*function)(); // here is error
}
int main()
{
Manager a;
a.timeCount(&Manager::passedFuction);
}
It works
call passedFunction
live demo

Function Objects vs State

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"; }
};

unique_ptr does not call the destructor to free the pointer

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.

How to use shared_ptr in a decorator pattern implementation correctly?

I am getting memory leak issues in the following code. I understand there are some flows. But not sure. How to use shared_ptr in these scenarios? And in case I need to add more decorators, say Chocolate-Pista-Icecream, how to pass the pointer correctly such that it will get deleted at the exit?
class AbstractCream
{
public:
virtual void ShowFlavour() = 0;
virtual ~AbstractCream()
{
cout << endl << "AbstractCream-DTOR";
}
};
class IceCream :public AbstractCream
{
public:
void ShowFlavour()
{
cout << "IceCream";
}
~IceCream()
{
cout << endl << "IceCream Dtor";
}
};
class DecoratorCream :public AbstractCream
{
private:
std::shared_ptr<AbstractCream> AbCream;
public:
DecoratorCream(std::shared_ptr<AbstractCream>abs) :AbCream(abs)
{}
void ShowFlavour()
{
AbCream->ShowFlavour();
}
virtual ~DecoratorCream()
{
cout << endl << "DecoratorCream-DTOR";
}
};
class ChocolateCream : public DecoratorCream
{
public:
ChocolateCream(std::shared_ptr<AbstractCream>abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "CholocateCream added..";
DecoratorCream::ShowFlavour();
}
~ChocolateCream()
{
cout << endl << "ChocolateCream-DTOR";
}
};
class PistaCream : public DecoratorCream
{
public:
PistaCream(std::shared_ptr<AbstractCream> abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "PistaCream added..";
DecoratorCream::ShowFlavour();
}
~PistaCream()
{
cout << endl << "PistaCream-DTOR";
}
};
class StrawberryCream : public DecoratorCream
{
public:
StrawberryCream(std::shared_ptr<AbstractCream> abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "StrawberryCream added..";
DecoratorCream::ShowFlavour();
}
~StrawberryCream()
{
cout << endl << "StrawberryCream-DTOR";
}
};
int main()
{
std::shared_ptr <AbstractCream> ice1( new IceCream());
std::shared_ptr <PistaCream> pista1(new PistaCream(ice1));
std::shared_ptr <AbstractCream> ice2(new IceCream());
std::shared_ptr <ChocolateCream>choco1( new ChocolateCream(ice2));
pista1->ShowFlavour();
cout << endl;
choco1->ShowFlavour();
cout << endl;
getchar();
_CrtDumpMemoryLeaks();
return 0;
}
The problem doesn't seem to be the std::shared_ptr<...> use in your classes: that seems to be semantically correct (it is too much code to review in detail, though). Instead, I think your main() is wrong: you try to determine memory leaks at point in time when the objects are still alive. I'm not a Windows program but I'm pretty sure that _CrtDumpMemoryLeak() doesn't know about std::shared_ptr<...> and simply reports newed memory which isn't deleted, yet.
There are a couple of simply ways to change your main() to avoid the problem:
Put the allocation of objects into a block and report memory leaks after the block:
int main() {
{
std::shared_ptr <AbstractCream> ice1( new IceCream());
// ...
}
_CrtDumpMemoryLeaks();
}
Put the code doing the actual work into a separate function and in main() just call this function and report on memory leaks:
int actualMain() {
std::shared_ptr <AbstractCream> ice1( new IceCream());
// ...
}
int main() {
int rc = actualMain();
_CrtDumpMemoryLeaks();
}
Report memory leaks from the destructor of an object which is constructed early, e.g., first thing in main():
struct Reporter { ~Reporter() { _CrtDumpMemoryLeaks(); } };
int main() {
Reporter reporter;
std::shared_ptr <AbstractCream> ice1( new IceCream());
// ...
}
With all three approaches the std::shared_ptr<...>s are destroyed before memory leaks are reported. I'm pretty sure that all of these approaches make the memory leaks go away. My preference would be the use of the third approach.
That said, the way the std::shared_ptr<...> are passed isn't ideal from a performance point of view: increments the reference count each time. When passing it through multiple layers it is unnecessarily bumped up while calling and bumped down when returning from the call. There are multiple ways to fix that problem, too:
The simple approach is to pass the std::shared_ptr<...> as a constant reference:
ChocolateCream(std::shared_ptr<AbstractCream> const& abs)
: DecoratorCream(abs) {
}
It can be argued that the pass by reference inhibits copy elision. However, argument construct can only be elided over one level: when passing the object on to another function it is a named object and the rules for copy elision allow eliding the copy from named objects only for return and throw statements. It may still be reasonable to go that route for the inner-most constructor. Even then, the std::shared_ptr<...> should be moved when passing it on (in that case to the construction of the member variable):
DecoratorCream(std::shared_ptr<AbstractCream> abs)
: AbCream(std::move(abs)) {
}
If you want to pass the argument by value in the other constructors, too, you should, at least, std::move(...) the argument. Doing so should avoid the reference count but it still won't avoid all work as it needs to construct/destroy a std::shared_ptr<...> on each level. However, at least, the synchronized maintenance of the reference count would be avoided.
Since I mentioned a performance problem: stop using std::endl. It doesn't do you much good. In your use it just slows down the program.
class AbstractCream
{
public:
virtual void ShowFlavour() = 0;
virtual ~AbstractCream()
{
cout << endl << "AbstractCream-DTOR";
}
};
class IceCream :public AbstractCream
{
public:
void ShowFlavour()
{
cout << "IceCream";
}
~IceCream()
{
cout << endl << "IceCream Dtor";
}
};
class DecoratorCream :public AbstractCream
{
private:
std::shared_ptr<AbstractCream> AbCream;
public:
DecoratorCream(const std::shared_ptr<AbstractCream> &abs) :AbCream(abs)
{}
void ShowFlavour()
{
AbCream->ShowFlavour();
}
virtual ~DecoratorCream()
{
cout << endl << "DecoratorCream-DTOR";
}
};
class ChocolateCream : public DecoratorCream
{
public:
ChocolateCream(const std::shared_ptr<AbstractCream>& abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "CholocateCream added..";
DecoratorCream::ShowFlavour();
}
~ChocolateCream()
{
cout << endl << "ChocolateCream-DTOR";
}
};
class PistaCream : public DecoratorCream
{
public:
PistaCream(const std::shared_ptr<AbstractCream> &abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "PistaCream added..";
DecoratorCream::ShowFlavour();
}
~PistaCream()
{
cout << endl << "PistaCream-DTOR";
}
};
class StrawberryCream : public DecoratorCream
{
public:
StrawberryCream(const std::shared_ptr<AbstractCream>& abs) :DecoratorCream(abs)
{}
void ShowFlavour()
{
cout << "StrawberryCream added..";
DecoratorCream::ShowFlavour();
}
~StrawberryCream()
{
cout << endl << "StrawberryCream-DTOR";
}
};
//-------------------dec--------------------------------------------------------------//
struct DummyToLeakCheck
{
public:
~DummyToLeakCheck()
{
_CrtDumpMemoryLeaks();
}
};
int main()
{
DummyToLeakCheck myLeakChecker;
std::shared_ptr <AbstractCream> ice1( new IceCream());
std::shared_ptr <PistaCream> pista1(new PistaCream(ice1));
std::shared_ptr <AbstractCream> ice2(new IceCream());
std::shared_ptr <ChocolateCream>choco1( new ChocolateCream(ice2));
std::shared_ptr <StrawberryCream>straw1(new StrawberryCream(choco1));
pista1->ShowFlavour();
cout << endl;
choco1->ShowFlavour();
cout << endl;
straw1->ShowFlavour();
cout << endl;
getchar();
return 0;
}
Using a Leak-checker as mentioned in the first answer helped correcting the original code.Modified code. Ignoring std::endl as of now, since the purpose of the code is to try out smart pointers in decorator pattern.

inheritance problem

I've messed up something.
Here is the code:
#include <iostream>
class connection_c {
private:
std::string data_;
void (*saveCallBack_)();
public:
connection_c(std::string &data) : data_(data) { std::cout << "ctor: " << __FUNCTION__ << ":" << data_ << std::endl;}
void registerCallBack(void(*cb)()) { saveCallBack_ = cb; }
};
class inst_c {
private:
static int id;
connection_c conn;
static void cb() { std::cout << __FUNCTION__ << " id = " << id << std::endl; }
public:
inst_c(connection_c &c, int a) : conn(c), id(a) {
std::cout << "ctor: " << __FUNCTION__ << " " << id << std::endl;
conn.registerCallBack(&cb);
}
};
class group_inst_c {
private:
connection_c conn;
inst_c i,j,k;
public:
group_inst_c(std::string data) : conn(data), i(conn,1), j(conn,2), k(conn,3) {}
};
int main() {
group_inst_c gi("asdf");
return 0;
}
What I want to achieve ;)
create a group of instances (group_inst_c)
it should initialize single connection for the group (connection_c)
each instance (inst_c) should use this connection (it will be serialized)
.. in addition each instance should register separate callback
For sure I've messed up with cloning, but I guess probably not only.
Can someone help me solve this puzzle? thx.
Your code creates a copy of your connection object for each instance. The original connection object is then only accessible by your group_inst_c. Is this what you want? If not, you need to change:
class inst_c {
private:
static int id;
connection_c& conn; // <-- Needs to be a reference.
in addition each instance should register separate callback
I'm not sure what you mean here. Are the callbacks supposed to be member functions? Then you need to use a "pointer to member function" (the ::*, .*, and ->* operators). If the callbacks are supposed to be regular functions, you should be okay with your current code. You'll just need to add this to class connection_c:
void doCallback(void) { (*saveCallBack_)(); }
If I understood that correctly (you want to call several callbacks from a single connection [object]), you need a list in connection_c to register the callbacks (just like delegates in C# if you know them).
If an event occurs to this connection, it has to know where to report. So you have to iterate through the callbacks somehow (call them one by one; you cannot call them all at once). The easiest, straightforward way is to use an STL list or maybe boost offers something appropriate.
Take a look at this: A C++ delegate class. In the main function, there's a vector defined that takes multiple callbacks. You could use this pattern in you connection_c class to add and not set a callback.
Try to keep it simple at first. There's always an opportunity to grow/improve the design later on. Below is some example code and here are a couple of things I was thinking about while building it:
1) As mentioned, keep it simple. For example, maybe the group concept can be a vector (i.e. inst_group_t) to start. You can always grow the design later as you learn more about it.
2) Try to reduce class dependencies. For example, maybe I do not need to have the connection as a member variable. I can pass it in when its needed (i.e. execute()). Maybe the callback doesn't need to be registered (i.e. execute()), since its 1 connection_c to many inst_c instances registering a callback for each inst_c would mean connection would have some container. Keep it simple :)
3) Try to use const and reference as much as possible (i.e. connection_c constructor). Less copy constructors/temp objects will be created.
#include <iostream>
class connection_c {
private:
std::string data_;
public:
connection_c(const std::string &data) : data_(data) {
std::cout << "ctor: " << __FUNCTION__ << ":" << data_ << std::endl;
}
};
class inst_c {
private:
int id;
public:
inst_c(int a) : id(a) {
std::cout << "ctor: " << __FUNCTION__ << " " << id << std::endl;
}
typedef void (*execute_callback_t)(int i);
void execute(connection_c& connection, execute_callback_t callback) {
callback(id);
}
};
void mycallback(int id) {
std::cout << "Instance number " << id << " executed" << std::endl;
}
int main() {
typedef std::vector<inst_c*> inst_group_t;
inst_group_t group;
std::string data;
connection_c connection(data);
for (int i = 0; i < 10; ++i)
group.push_back(new inst_c(i) );
for (int i = 0; i < 10; ++i)
group[i]->execute(connection, mycallback);
for (int i = 0; i < 10; ++i)
delete group[i];
return 0;
}