Nie potrafię zrozumieć zasad przekazywania inteligentnych wskaźników, czy mógłby mi ktoś to lepiej wyjaśnić? Głównie zależy mi na łopatologiczny wyjaśnieniu, kiedy shared_ptr powinnien być przekazywany przez wartość, a kiedy przez referencję, const referencję.
W kodzie znajdują się pytania.
Czy zawsze dajecie noexcept
jeśli funkcja jest noexcept? Np. getter, setter czy tylko jeśli da to wzrost wydajności np. move semantic.
Co w przypadku desktruktora, zawsze noexcept? Co jeśli destruktor z jakiegoś dziwnego powodu korzysta z operatora delete
, czy wtedy też dajecie noexcept? Teoretycznie delete
jest noexcept, ale delete ptr; delete ptr;
to UB i wtedy może być rzucany wyjątek. W takim razie czy jeśli funkcja potencjalnie wywołuje UB to czy jest noexcept?
Kod przykładowy do pytań o pointery:
#include <iostream>
#include <memory>
class Foo
{
public:
Foo() = default;
Foo(const std::shared_ptr<int>& ptr) : ptr(ptr){} // Ptr w klasie jest drugim właścicielem. Dobrze?
Foo(std::shared_ptr<int> ptr) : ptr(std::move(ptr)){} // Czy tak?
void print() const
{
std::cout << x << '\n';
}
void change() noexcept // noexcept?
{
x = 5;
}
private:
int x = 3;
std::shared_ptr<int> ptr;
};
void useUniquePtr(std::unique_ptr<Foo> ptr) // Funkcja staje się właścicielem i usuwa wskaźnik
{
ptr->change();
ptr->print();
}
void useUniquePtr(const std::unique_ptr<Foo>& ptr) // Funkcja chce użyć wskaźnik, ale może też nie użyć
{
if(ptr)
{
ptr->change();
ptr->print();
}
}
// w innych przypadkach użycie powinno się użyć shared_ptr
void useSharedPtr(const std::shared_ptr<Foo>& ptr) // Funkcja chce użyć wskaźnik, ale może też nie użyć
// Jak ma wyglądać ciało funkcji, tak, czy tak jak niżej?
{
try
{
if(ptr)
{
ptr->change();
ptr->print();
}
else
{
throw("Co za dzban usunął pointer, bug w kodzie\n");
}
}
catch(const std::string& ex)
{
std::cout << ex;
}
}
void useSharedPtr(std::shared_ptr<Foo> ptr) // nowy współwłaściciel
{
ptr->change();
ptr->print();
}
int main()
{
auto unique = std::make_unique<Foo>();
auto shared = std::make_shared<Foo>();
return 0;
}
Ceponoexcept
funkcja nie rzuci wyjątku, czy źle zrozumiałem?alagnernoexcept
cały program zdechnie jeżeli z funkcji tak oznaczonej miałby się wydostać wyjątek...no więc poniekąd ona nie rzuci. Ew. rzuci raz a dobrze: https://godbolt.org/z/KTv53xfnM