shared_ptr i kopiowanie this

0

Witam na studiach mam zadanie zrobić wypożyczenie Rent tak żeby Client wiedział co ma wypożyczone.
problem ten rozwiązałem wykonując oznaczoną linię kodu lecz ta linia jest odpowiedzialna za podwójne zwolnienie pamięci co owocuje błędem gdy program sprząta po sobie

czytałem o std::enable_shared_from_this lecz nie potrafię tego zastosować
metoda Clienta addRents jest odpowiedzialna za dodanie Rent do wektora typu shared_ptr<rent>

Rent::Rent(std::shared_ptr<Client> cClient, std::shared_ptr<Vehicle> cVehicle, local_date_time cRentalDateTime)
        : rentalDateTime{cRentalDateTime}, returnDateTime {not_a_date_time}, client(cClient), vehicle(cVehicle)
{
    this->_uuid = boost::uuids::uuid(boost::uuids::random_generator()());
    this-> vehicleRented=true;
    client->addRents(std::shared_ptr<Rent>(this));  // linijka odpowiadająca za błąd
   // this->
    this->vehicle->setIsRented(true);
}
0

Idąc dokumentacją: http://en.cppreference.com/w/cpp/memory/enable_shared_from_this

Definicja klasy Rent powinna wyglądać tak:

// w pliku .h:
class Rent : public std::enable_shared_from_this<Rent>
{
public:
  Rent(std::shared_ptr<Client> cClient, std::shared_ptr<Vehicle> cVehicle, local_date_time cRentalDateTime);

 // .. składniki klasy, metody itp.
};
// w pliku .cpp:
Rent::Rent(std::shared_ptr<Client> cClient, std::shared_ptr<Vehicle> cVehicle, local_date_time cRentalDateTime)
        : rentalDateTime{cRentalDateTime}, returnDateTime {not_a_date_time}, client(cClient), vehicle(cVehicle)
{
    this->_uuid = boost::uuids::uuid(boost::uuids::random_generator()());
    this-> vehicleRented = true;
    client->addRents(shared_from_this());
    this->vehicle->setIsRented(true);
}


Wtedy musisz każdy obiekt klasy Rent trzymać w std::shared_ptr (tworząc go przez std::make_shared) póki wywołujesz powyższy konstruktor.

EDIT: Patrz posty niżej.

1

Po pierwsze shared_from_this wymaga żeby istniał już co najmniej jednen shared_ptr tego typu, więc wołanie tego w konstruktorze to UB. Po drugie, po kiego grzyba ci w ogóle te shared_ptry?

0

Wymagania zadania są takie żeby Rent miał informacje o Client oraz Client miał informacje o Rent
terminate called after throwing an instance of 'std::bad_weak_ptr'
what(): bad_weak_ptr
Przerwane (zrzut pamięci)

0
krecikondexin napisał(a):

Wymagania zadania są takie żeby Rent miał informacje o Client oraz Client miał informacje o Rent

Ktoś uczy was złych praktyk programowania. W dobrej architekturze wszelkie cykliczne zależności powinny być unikane.

1

Pomijając cykl takie coś rozwiązuje się za pomocą wzorca two step initialization.

auto Rent::Create(std::shared_ptr<Client> cClient, std::shared_ptr<Vehicle> cVehicle, 
           local_date_time cRentalDateTime)
    -> std::shared_ptr<Rent>
{
    auto result = std::make_shared<Rent>();
    client->addRents(result); // ja tu przewiduje widzę wyciek pamięci
    … … …
    return result;
}

Rent::Rent()
    : returnDateTime {not_a_date_time}
{
    this->_uuid = boost::uuids::uuid(boost::uuids::random_generator()());
    this-> vehicleRented=true;
}
0

std::weak_ptr, możesz poczytać też inne dokumentacje pointer'a np. w boost lub Qt...

ogólnie zainicjuj te shared_ptr obiektów, po czym przekaż im na wzajem "wskaźnik" do zmiennej klasy weak_ptr... gdy będziesz potrzebował pozyskać informację po prostu w ciele metody inicjujesz o ile się da shared_ptr... można by to rozwiązać jeszcze inaczej przy pomocy jakiegoś obiektu pośredniczącego...

0

two step initialization, odpada, program przechodzi jakieś testy gdzie niektóre konstruktory i metody muszą mieć określony wygląd, ten konstruktor musi być taki :/

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0