RxCpp经常调用复制构造函数。

问题描述 投票:1回答:1

我试图在我的程序中加入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 我想用它来发布一个在网络操作完成后在堆栈上创建的对象。在这种情况下,copy构造函数被调用了4次(仅有?

我理解,调用复制构造函数是必要的,因为可能有多个观察者在监听,他们不能共享一个移动的对象。我也希望观察者上的每个操作者就像另一个订阅者一样。

然而,我不明白为什么内部会发生这么多,尤其是在这个例子中。这感觉像是我做错了什么。有什么办法可以优化这个问题吗?另外,如果只有一个subscriber,是否有一个很好的理由不使用move构造函数?

一般来说,使用 std::shared_ptr 通过观察器发射较大的对象以避免调用复制构造函数?

c++ reactivex rxcpp
1个回答
0
投票

是的,rxcpp做了很多拷贝。负担在于值要便宜的可复制。

欢迎使用PR,但必须保留现有的模式,即允许每个subscribe()被多次调用。

这意味着每次调用subscribe都会创建一个订阅,并且必须为该订阅的值做一个副本。

如果subscribe是线程上的第一个subscribe(如本例),它本身会做一个额外的步骤。它使用当前的线程调度器来获取该线程的所有权。这很可能将发送者复制到调度工作中。这是一个可以保存一些副本的情况。

just()本身很可能使用指定的调度器arg调度对on_next的调用,本例中默认为当前线程调度器,再复制一份值。

© www.soinside.com 2019 - 2024. All rights reserved.