Страницы

Поиск по вопросам

воскресенье, 16 февраля 2020 г.

Будет ли копироваться значение при передаче умных указателей в функцию или будет передаваться ссылка?

#cpp #указатели


Например, имеется некоторый класс:

class CSomeClass
{
    double GetLengthLine(std::shared_ptr firstVertex, std::shared_ptr
secondVertex) const;
}




double CTriangle::GetLengthLine(std::shared_ptr firstVertex, std::shared_ptr
secondVertex) const
{
    ....
    return std::hypot(dx, dy);
};


Будет ли копироваться значение при передаче умных указателей в функцию, или будет
передаваться ссылка?
    


Ответы

Ответ 1



Если я правильно понял вопрос (хотя на этот счет есть сомнение, т.к. уже имеется принятый ответ), то речь всё же о копировании объекта типа CPoint, которым параметризован std::shared_ptr. В этом случае совершенно не важно как будет передаваться объект умного указателя по ссылке или по значению - это не приведет к дополнительному копированию объекта, хранимого в указателе. Пример: #include #include struct S { S() { std::cout << "ctor\n"; } S(const S&) { std::cout << "copy\n"; } S(S&&) { std::cout << "move\n"; } }; void f(std::shared_ptr) {} void g(const std::shared_ptr&) {} int main(){ auto s = std::make_shared(); f(s); g(s); } Вывод: ctor Т.е. был создан только один объект. Ни копирований, ни перемещений не произошло. Это в принципе логично, т.к. подобным же образом не происходит создания (полезных) объектов при передаче обычных (не умных) указателей. В общем случае, любой достаточно большой (более нескольких sizeof(int)) объект имеет смысл передавать по константной ссылке, если не предполагается его модифицировать.

Ответ 2



Так как параметры ваших функций принимают объект типа std::shared_ptr по значению, то в функции будут передаваться копии аргументов, с которыми они вызваны. То есть соответствующий аргумент либо будет перемещаться, либо копироваться в параметр функции, так как класс std::shared_ptr имеет как конструктор копирования, так и конструктор перемещения. Но будет меняться число ссылок на тот указатель, который обернут в std::shared_ptr. То есть при вызове функций будет меняться счетчик ссылок на исходный "сырой" указатель. Рассмотрите следующую демонстрационную программу. #include #include void f( std::shared_ptr p ) { std::cout << "Inside f() shared_ptr::use_count() = " << p.use_count() << std::endl; } int main() { std::shared_ptr p( new int ( 10 ) ); std::cout << "Before calling f shared_ptr::use_count() = " << p.use_count() << std::endl; f( p ); std::cout << "Aftera calling f shared_ptr::use_count() = " << p.use_count() << std::endl; return 0; } Ее вывод на консоль следующий Before calling f shared_ptr::use_count() = 1 Inside f() shared_ptr::use_count() = 2 After calling f shared_ptr::use_count() = 1

Комментариев нет:

Отправить комментарий