我正在尝试将RxCpp包含在我的程序中,并且我注意到,该框架调用了很多已发出对象的复制构造函数。
#include <iostream>
#include <rxcpp/rx.hpp>
class Foo
{
public:
Foo() = default;
Foo(Foo const &other)
{
std::cout << "Copy constructor called" << std::endl;
};
Foo(Foo &&other) noexcept
{
std::cout << "Move constructor called" << std::endl;
};
};
int main()
{
Foo bar;
rxcpp::sources::just(std::move(bar))
.subscribe(
[](Foo const &baz)
{
std::cout << "Foo received" << std::endl;
}
);
return 0;
}运行此输出
Move constructor called
Copy constructor called
Move constructor called
Move constructor called
Move constructor called
Move constructor called
Move constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Copy constructor called
Foo received我首先在subject上注意到这一点,我想用它发布一个在网络操作完成后在堆栈上创建的对象。在这种情况下,复制构造函数被调用(仅?)4次,但没有操作员在其间操作,主题只有一个订阅者。
我理解,调用复制构造函数是必要的,因为多个观察者可能正在监听,它们不能共享移动的对象。我还期望观察者上的每个操作员就像另一个订阅者一样。
然而,我不明白为什么它会在内部发生这么多,特别是在这个例子中。这感觉像是我做错了什么。有什么方法可以优化这一点吗?还有,如果只有一个订阅者,为什么不使用move构造函数呢?
通常情况下,使用std::shared_ptr通过observable发出较大的对象以避免复制构造函数调用是一个好主意吗?
发布于 2020-05-02 08:11:28
是的,rxcpp做了很多拷贝。负担在于可廉价复制的价值。
PR是受欢迎的,但必须保留现有模型,允许多次调用每个subscribe()。
这意味着每次调用subscribe都会创建一个订阅,并且必须为该订阅创建一个值的副本。
如果Subscribe是线程上的第一个subscribe (如本例所示),则subscribe本身会执行额外的步骤。它使用当前的线程调度程序来取得线程的所有权。这很可能会将发送者复制到排定的工时中。这是一种可以保存一些副本的情况。
just()本身可能会使用指定的调度器arg来调度对on_next的调用,在本例中,调度器arg默认为当前线程调度器,并带有该值的另一个副本。
https://stackoverflow.com/questions/61547214
复制相似问题