函数对象与状态
Function Objects vs State
我使用函数对象来找出传递的对象会发生什么,以及它如何影响对象的状态。下面是测试代码的片段:
#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
*/
当我使用运算符 (( 重载传递对象时,有一些对析构函数的多次调用;并且没有创建任何对象!所以,我不能依赖,可以这么说,对象状态的保真度。这是否意味着当我传递一个函数对象(带有重载运算符(((进行回调时,我应该假设对象的状态没有保留?这是预期的行为吗?
另一方面,从另一种类型的对象内部回调绑定成员函数会产生非常稳定的行为(我不知道使用什么术语(;也就是说,我希望对象状态得到保留;确实如此!这也是有意的行为吗?IOW,这是通常理解函子的方式吗?
附注:
我还用boost::function和boost::bind ---检查了它,结果非常相似。可能需要另一个线程来讨论细微差别。
关于"无构造函数":有对复制构造函数的调用。
尝试更多仪器:
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"; }
};
关于复制:
- 您将可调用的 by 值交给 B 的构造函数。它必须被复制。
- 绑定,如果您提交值,这是预期的行为。您交给绑定的可调用对象可能是临时的。因此,默认行为是复制。
如果您知道可调用对象将存活足够长的时间(就像代码中的情况一样(,则可以通过使用引用包装器来避免这种情况。尝试:
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;
}
当我使用运算符 (( 重载传递对象时,有一些对析构函数的多次调用;并且没有创建任何对象!
您不计算使用复制构造函数构造的对象,该构造函数由编译器在您不提供任何对象时创建。
将复制构造函数添加到A
您将看到对析构函数的调用次数与对构造函数的调用次数相同。
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"; }
};
相关文章:
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 在容器上移动分配:以前包含的对象的状态
- MATLAB:跟踪imufilter对象中的状态变化
- 是否很好地使用状态模式来维护当前选定的对象?
- "Extern"对象问题:错误:Id 返回 1 个退出状态
- 访问处于"移自"状态的对象
- 是 *this = Ctor();清除对象状态的合法和高效?
- 设计模式中对象中的过程(方法和操作)的状态
- 如何保持异步函数中使用成员的shared_ptr对象的活动状态?
- 无法访问/存储地图中的游戏状态对象
- 类的堆分配对象是否在其作用域之后但在 C++ 中调用其析构函数之前处于活动状态
- 当对象的当前状态不允许在其上进行操作时,要投掷哪个例外
- 单元测试 - 设置私人成员以获得所需的对象状态
- OpenCV 中 VideoCapture 对象的状态
- 过滤器抱怨对象保持活动状态
- 如何安全地更改状态对象之间的状态
- 在处理无状态对象时,将它们标记为const是否仍有性能优势
- boost::MPI 的 irecv() 返回未初始化的状态对象
- 如何从状态对象本身而不是外部改变状态
- 在DirectX 12中,切换管道状态对象的性能如何?