Я пытаюсь включить Rx Cpp в мою программу, и я заметил, что фреймворк довольно часто вызывает конструктор копирования излучаемых объектов.
#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
, с помощью которого я хотел опубликовать sh объект, созданный в стеке после завершения сетевой операции. В этом случае конструктор копирования вызывался (только?) 4 раза, но между ними не было операторов, и у субъекта был только один подписчик.
Я понимаю, что вызов конструктора копирования необходим, поскольку несколько наблюдатели могут слушать, и они не могут разделить перемещенный объект. Я также ожидаю, что каждый оператор на наблюдаемой точно так же, как и другой подписчик.
Однако я не понимаю, почему это происходит внутри, особенно в этом примере. Такое ощущение, что я сделал что-то не так. Есть ли способ оптимизировать это? Также есть ли веская причина, по которой конструктор перемещения не используется, если имеется только один подписчик?
Как правило, целесообразно использовать std::shared_ptr
для излучения больших объектов через наблюдаемое, чтобы избежать вызовов конструктора копирования?