Rzutowanie referencji na wskaźnik klasy bazowej do referencji na wskaźnika klasy pochodnej
Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Zarejestruj się!

Rzutowanie referencji na wskaźnik klasy bazowej do referencji na wskaźnika klasy pochodnej

AutorWiadomość
Temat założony przez niniejszego użytkownika
Rzutowanie referencji na wskaźnik klasy bazowej do referencji na wskaźnika klasy pochodnej
» 2019-08-23 21:27:42
Cześć,

Mam dwie klasy: bazową Test oraz pochodną TestDerived.
Klasa bazowa zawiera referencję do wskaźnika obiektu klasy bazowej, który znajduję się w innej części programu.
Potrzebuję referencji do wskaźnika, aby móc wykryć usunięcie pamięci z powodu jakiegoś innego zdarzenia nie związanego z obiektem, który ma tą referencje.

To jest tylko kod przykładowy (testowy). Nie ma co zastanawiać się nad jego sensem.

C/C++
class Test {
public:
    Test( Test *& refTest )
        : refTest( refTest )
    { }
    virtual ~Test();
   
    Test *& refTest;
    Test *& getRefTest() { return refTest; }
   
};

Test::~Test() {
   
}


class TestDerived
    : public Test
{
public:
    TestDerived( Test *& refTest )
        : Test( refTest )
    { }
    virtual ~TestDerived() override;
   
};

TestDerived::~TestDerived() {
   
}

Zdarza się jednak sytuacja, w której potrzebuję wykorzystać ten wskaźnik i jestem pewny, że mogę bezpiecznie rzutować na wskaźnik typu TestDerived, który jest mi potrzebny jeszcze w innym miejscu, ale jest to ten sam obiekt tylko typu TestDerived.

Chciałbym rzutować typ Test*& na TestDerived*&, który jest podawany do innego obiektu, a właśnie w postaci TestDerived*&.

Problemem jest jednak to, że nie mogę tego zrobić, a chciałbym się dowiedzieć, co mogę zrobić w tej sytuacji.

Poniżej przykład tego co próbuję zrobić, tylko tu chcę tylko rzutować.

C/C++
void main() {
    Test * test = nullptr;
    Test * tD = new TestDerived( test );
    test = new Test( tD->getRefTest() );
    Test *& testRef =( test->getRefTest() );
    TestDerived *& testDRef = static_cast < TestDerived *&>( testRef );
}

PS.
Potrzebuję tego, ponieważ korzystam ze struktury danych przechowujących obiekty z parametrami obiektów.

Dwie inne klasy:

Jedna do przechowywanie instancji obiektu, który jest aktualnie modyfikowany i mam referencję do wskaźnika obiektu w bazie danych. W momencie zapisu, wykonuję usunięcie i podstawienie obiektu z pomocą metod bazy danych.

Druga do przechowywanie referencji do wskaźnika obiektu w bazie danych. W momencie zapisu z pomocą klasy przedstawionej wyżej mam aktualizowane dane w tym drugim obiekcie.


P-175104
» 2019-08-23 22:48:23
Do bezpiecznego rzutowania w dół służy
dynamic_cast
.

» Programowanie obiektowe, C++ » PolimorfizmKonwersja w górę i rzutowanie w dół lekcja
P-175105
» 2019-08-23 22:49:34
Potrzebuję referencji do wskaźnika, aby móc wykryć usunięcie pamięci z powodu jakiegoś innego zdarzenia nie związanego z obiektem, który ma tą referencje.
To radze poczytać co to jest shared_ptr.

i w ogóle trzymanie referencji na wskaźnik jako składową klasy nie brzmi jak dobry pomysł.

Potrzebuję tego, ponieważ korzystam ze struktury danych przechowujących obiekty z parametrami obiektów.
nie wiem co przez to rozumiesz ale to też nie wygląda na problem którego rozwiązaniem jest referencja na wskaźnik lub rzutowanie.

Spróbuj może opisać problem jaki masz zamiast rozwiązania które szukasz, może jest coś lepszego co możemy ci zaproponować.
P-175106
» 2019-08-23 23:54:19
C/C++
//static
template < class T >
std::shared_ptr < T > Base < T >::create()
{
    auto refObject = std::make_shared < T >();
    refObject->mref_this = refObject;
    return refObject;
}

//klasa Base powinna mieć pole:
//std::weak_ptr<Base> mref_this;
Wówczas możesz uzyskać zawsze poprawny uchwyt do obiektu, który utworzyłeś. W kodzie mogą być błędy, ale koncepcyjnie możesz się zastanowić czy spełni to Twoje oczekiwania.

Do rzutowania std::shared_ptr<> istnieją również funkcje więc... wszystko co potrzeba da się uzyskać.
P-175107
Temat założony przez niniejszego użytkownika
» 2019-08-24 11:03:31
Dzięki za odpowiedź.

Co do użycia dynamic_cast<>, wiem, że do służy do bezpiecznego rzutowania, ale nie mam potrzeby sprawdzania, czy obiekt mogę bezpiecznie zrzutować, ponieważ ze struktury kodu wynika, że mogę bezpiecznie zrzutować.

Co do przedstawionego przeze mnie problemu, doszedłem do wniosku, że nie jestem w stanie sprawdzić, czy obiekt został usunięty, ponieważ w tym czasie w miejscu usuniętego wskaźnika ustawionego na null, może pojawić się inna pamięć, co będzie skutkować, niszczeniem pamięci.

Z tego samego powodu nie będzie działał shared_ptr.

P-175108
» 2019-08-24 14:22:32
Co do przedstawionego przeze mnie problemu, doszedłem do wniosku, że nie jestem w stanie sprawdzić, czy obiekt został usunięty, ponieważ w tym czasie w miejscu usuniętego wskaźnika ustawionego na null, może pojawić się inna pamięć, co będzie skutkować, niszczeniem pamięci.

Z tego samego powodu nie będzie działał shared_ptr.
Dlaczego nie jesteś w stanie sprawdzić, że usunąłeś obiekt? To jest cały sens używania shared_ptr<> z weak_ptr<>.
C/C++
#include <iostream>
#include <memory>

int main()
{
    std::shared_ptr < int > sp = std::make_shared < int >( 123 );
   
    std::weak_ptr < int > wp = sp;
    std::cout <<( void * ) wp.lock().get() << '\n';
   
    sp = std::make_shared < int >( 456 );
    std::cout <<( void * ) wp.lock().get() << '\n';
}
0x1c2500
0

Chciałbym rzutować typ Test*& na TestDerived*&, który jest podawany do innego obiektu, a właśnie w postaci TestDerived*&.
Nie możesz rzutować referencji per se. Nazwa referencji jest l-wartością na wskazywany typ, a nie typu "referencja na wskazywany typ". Co możesz zrobić, to pobrać adres wskaźnika, rzutować ten na TestDerived** (już nie static_castem) i po dereferencji będziesz mieć TestDerived*&. Generalnie to jest hack, a nie coś czego powinieneś używać.
P-175109
Temat założony przez niniejszego użytkownika
» 2019-08-24 14:42:16
Ok, jednak będzie działać. Dzięki za wyjaśnienie. Jednak i tak doszedłem do wniosku, że lepiej będzie inaczej zaprojektować aplikację.

Do korzystania z podejścia programowania, które wyjaśniliście, skorzystam przy innej aplikacji, gdy będę miał więcej czasu.
P-175110
« 1 »
 Strona 1 z 1