Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Różnica między make_shared a new.

Ostatnio zmodyfikowano 2020-02-21 20:03
Autor Wiadomość
zerotwarzygreya
Temat założony przez niniejszego użytkownika
Różnica między make_shared a new.
» 2020-02-21 17:06:58
Cześć, mógłby ktoś mi wytłumaczyć czemu instrukcja w komentarzu jest nieprawidłowa ? Poniżej podaje link do projektu.

Link do projektu:  https://drive.google.com/file​/d​/1d_VJ01S_amjS6MRylal2yCqW1Qme​O3A2​/view



C/C++
Query operator |( const Query & lhs, const Query & rhs )
{
    //return shared_ptr<Query_base>(make_shared<Query_base> (OrQuery(lhs, rhs)));
    return shared_ptr < Query_base >( new OrQuery( lhs, rhs ) );
}
P-176260
DejaVu
» 2020-02-21 18:24:15
C/C++
return std::make_shared < OrQuery >( lhs, rhs );

W skrócie: make_shared zwraca już shared_ptr-a.

/edit:
A gdybyś jeszcze miał błąd kompilacji to dorzuć static_pointer_cast.

http://www.cplusplus.com​/reference/memory​/static_pointer_cast/
P-176261
zerotwarzygreya
Temat założony przez niniejszego użytkownika
» 2020-02-21 18:33:48
Pszepraszam, trochę nieprecyzyjnie się wyraziłem wiem, że w przypadku użyciu make_shared jest rezerwowany tylko jeden blok na pamięć (na liczbę rekurencji oraz na sam obiekt)  a w przypadku new dwa. Nie rozumiem tylko dlaczego kod w komentarzu nie działa (kod z new działa). W przypadku gdy zwracam shared_ptr przy pomocy make_shared wyświetla się błąd kompilacji.
Severity Code Description Project File Line Suppression State
Error C2259 'Query_base': cannot instantiate abstract class Z C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.24.28314\include\xmemory 1969
P-176262
DejaVu
» 2020-02-21 19:17:58
std::make_shared tworzy samemu obiekt, więc sam nie wykonujesz alokacji (make_shared robi to za Ciebie i przy okazji poprawnie obsługuje sytuację w przypadku braku pamięci). Twój zapis wywołuje tworzenie obiektu bazowego (bo taki przekazałeś w parametrze szablonu). Obiekt bazowy (Query_base) jest abstrakcyjny, więc dostajesz błąd kompilacji (i taki sam błąd otrzymałbyś, gdybyś chciał utworzyć obiekt bazowy (Query_base) za pomocą operatora new).
P-176263
zerotwarzygreya
Temat założony przez niniejszego użytkownika
» 2020-02-21 19:48:43
Super, dzięki już rozumiem. A ten fragment z operatorem new to miałeś na myśli coś takiego Query_base* q = new Query_base ?
P-176264
mizie
» 2020-02-21 19:54:53
O ile się nie mylę twój wycinek kodu pochodzi z pliku OrQuery.cpp. Jeżeli chcesz, żeby kod działał z wykorzystaniem make_shared() jednym z rozwiązań jest poniższe (jako argumenty podajesz parametry konstruktora OrQuery):

C/C++
#include "OrQuery.h"
ResultQuery OrQuery::eval( const TextQuery & obj ) const {
    auto res1 = a.eval( obj );
    auto res2 = b.eval( obj );
    auto line = make_shared < set < int >>( res1.begin(), res1.end() );
    line->insert( res2.begin(), res2.end() );
    return ResultQuery( rep(), res1.get_file(), line );
}

Query operator |( const Query & lhs, const Query & rhs ) {
    /*Might not work- check difference between make_shared and new allocation */
    shared_ptr < Query_base > qbptr = make_shared < OrQuery >( lhs, rhs );
    return qbptr;
    // return shared_ptr<Query_base>(new OrQuery(lhs, rhs));
}

Ponadto musisz upublicznić konstruktor w pliku OrQuery.h (szczerze powiedziawszy nie wiem czemu mają służyć w tym przypadku konstruktory w sekcji private, ale też nie analizowałem kodu zbyt dokładnie) w następujący sposób:

C/C++
#pragma once
#include "BinaryQuery.h"
class OrQuery
    : public BinaryQuery
{
    friend Query operator |( const Query & lhs, const Query & rhs );
public:
    OrQuery( const Query & lhs, const Query & rhs )
        : BinaryQuery( lhs, rhs, "|" )
    { }
private:
    ResultQuery eval( const TextQuery & obj ) const override;
};

Projekt po wprowadzeniu tych zmian i kompilacji dał następujący rezultat:
Executing query for: ((fiery & bird) | wind)
((fiery & bird) | wind) occurs 3 times
Line 2) Her Daddy says when the wind blows
Line 4) like a fiery bird in flight.
Line 5) A beautiful fiery bird, he tells her,
P-176265
DejaVu
» 2020-02-21 19:55:05
@zerotwarzygreya: Mniej więcej tak.

@up: będzie błąd kompilacji w Twoim przypadku, ponieważ CHYBA std::shared_ptr<QueryBase> != Query.
P-176266
zerotwarzygreya
Temat założony przez niniejszego użytkownika
» 2020-02-21 20:00:59
Dzięki jeszcze raz za pomoc temat do zamknięcia. Btw. wszystkie konstruktory (prócz tych z klas abstrakcyjnych) są private ponieważ klasa Query jest interfacem do nich.
P-176267
« 1 » 2
  Strona 1 z 2 Następna strona