CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - niszczenie "obiektów" klasy wewnątrz konstruktora

niszczenie "obiektów" klasy wewnątrz konstruktora

dział ogólny

niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Slynx » poniedziałek, 11 kwietnia 2011, 11:58

Pewna klasa:
KOD cpp:     UKRYJ  
// to jest zawartość konstruktora, w konstruktorze podawany jest tylko jeden argument - host;
// dokładniej - plik cpp

                switch (host)
                        {
                        case 1:
                                this->host_1 = gcnew Mail::Host_1();
                                delete this->host_2;
                                break;
                        case 2:
                                this->host_2 = gcnew Mail::Host_2();
                                delete this->host_1;
                                break;
}
 


W pliku .h mam:

KOD cpp:     UKRYJ  
[..]
                        Mail::Host_1^ host_1;
                        Mail::Host_2^ host_1;
[...]


i w przypadku wywołania, tak jak wynika z kodu, jeden obiekt powinien być tworzony, a drugi "obiekt" (a raczej tylko definicja typu), zniszczony.
Kod się kompiluje, ale nie działa jak należy. Do obiektu stworzonego i tego niestworzonego można się tak samo odwołać.
Chciałbym żeby po prostu nie było po nim śladu i już nie był dostępny.
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez polymorphism » poniedziałek, 11 kwietnia 2011, 14:19

Obiekty stworzone przez gcnew są pod kontrolą garbage collectora, a on nie musi usuwać (pamięci) obiektów od razu.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2157
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Slynx » poniedziałek, 11 kwietnia 2011, 14:50

Za szybko czytasz i znów za mało rozumiesz. Przyjrzyj się jeszcze raz. Ja mówiłem o tym
KOD cpp:     UKRYJ  
Mail::Host_2^ host_1;
 

a nie o tym
KOD cpp:     UKRYJ  
this->host_1 = gcnew Mail::Host_1();
 

Tak jak napisałem, jeśli poprzez switch zostanie stworzony host_1 to host_2 powinien zostać...hmm.. usunięty ?
Bo jeśli dobrze zrozumiałem to co napisałem w kodzie, to gdy host_1 stanie się obiektem z przydzieloną pamięcią, to host_2 pozostanie tylko deklaracją obiektu klasy Host_2. A chciałbym by było tak, że gdy obiekt host_1 zostanie stworzony to host_2 przestanie kompletnie istnieć.

Mój błąd, bo dałem trochę za mało kodu i mogłeś po prostu nie zrozumieć.

Te deklaracja w pliku .h są globalne. Nie za bardzo wiedziałem jak stworzyć obiekt konkretnej klasy w zależności od wartości argumentu w konstruktorze, więc po prostu stworzyłem globalne deklaracje obiektów wszystkich możliwych klas jakie mogą być wykorzystane przez konstruktor. A potem poprzez konstruktor i switch wybierana jest konkretna deklaracja i tworzony jest obiekt tej klasy przez gcnew.
Nie wiem czy dobrze się wyraziłem, ale mam nadzieję, że rozumiesz co chciałem powiedzieć ;)
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Cyfrowy Baron » poniedziałek, 11 kwietnia 2011, 15:05

Slynx napisał(a):W pliku .h mam:

KOD cpp:     UKRYJ  
                        Mail::Host_1^ host_1;
                        Mail::Host_2^ host_1;


Nie wiem czy to błąd w kodzie, czy na prawdę tak masz, ale widzę tutaj deklarację dwóch obiektów, dwóch różnych klas, ale o identycznej nazwie host_1. No chyba, że w C++/CLI to jest coś zupełnie naturalnego, ale gdyby nawet to definicje już się z tym nie pokrywają:

KOD cpp:     UKRYJ  
 case 1:
        this->host_1 = gcnew Mail::Host_1(); /* ... */
 case 2:
        this->host_2 = gcnew Mail::Host_2();


W C++ coś takiego by nie przeszło, gdyż nie można zadeklarować, a co za tym idzie rezerwować pamięci dla dwóch różnych obiektów o identycznej nazwie, poza sytuacją, gdy jeden obiekt jest globalny, publiczny, lub prywatny, a drugi jest lokalny.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez polymorphism » poniedziałek, 11 kwietnia 2011, 15:10

Za szybko czytasz i znów za mało rozumiesz.

Rozumiem tyle, ile napiszesz. Więc jeśli czegoś nie zrozumiałem, na 80% źle opisałeś problem.

Jeśli tym razem dobrze Ciebie zrozumiałem, to w C++ nie da się usunąć definicji zmiennej w runtime'ie. Zresztą po co to robić?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2157
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Slynx » poniedziałek, 11 kwietnia 2011, 15:42

C.Baronie. Tam była pomyłka. Miało być host_2. Widocznie się machnąłem.

Polymorphism, pytasz po co. Mi to teoretycznie w niczym nie przeszkadza, ale chciałbym by można było się dostać tylko do stworzonego obiketu w switch, a tak to zostają te "resztki", przez które też można się odwołać (do innych klas), ale które nie są nowymi obiektami.
No ale cóż, nie da się to trudno.
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Cyfrowy Baron » poniedziałek, 11 kwietnia 2011, 17:31

Slynx napisał(a):C.Baronie. Tam była pomyłka. Miało być host_2. Widocznie się machnąłem.


Tak też przypuszczałem.

Jak rozumiem deklarujesz obiekty jako globalne, ale chcesz żeby były dostępne tylko lokalnie, wewnątrz bloku switch?! Tak należy rozumieć Twój problem???
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Slynx » wtorek, 12 kwietnia 2011, 12:35

Nie. Przyjrzyj się jeszcze raz. W bloku switch, czyli wewnątrz konstruktora ja jedynie tworzę te obiekty dla wcześniej stworzonych deklaracji (globalne - host_1 i host_2)
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Cyfrowy Baron » wtorek, 12 kwietnia 2011, 12:52

Slynx napisał(a):W bloku switch, czyli wewnątrz konstruktora


Blok switch nie jest konstruktorem, ale jak rozumiem to taki skrót myślowy...

Slynx napisał(a): ja jedynie tworzę te obiekty dla wcześniej stworzonych deklaracji (globalne - host_1 i host_2)


No to w czym problem. Obiekty mające deklarację globalną, tworzone lokalnie, gdzie by to nie było, będą dostępne globalnie, jak długo nie zostaną zniszczone.



po chwili... :?

...już się domyśliłem.

Deklarujesz dwa obiekty, ale tworzysz tylko jeden obiekt wewnątrz konstruktora klasy - na przyszłość zamieszczaj pełniejszy kod by było widać, ze to jest w konstruktorze. Chcesz usunąć zbędny obiekt, ale masz tam błąd, gdyż tworząc np. host_1 jednocześnie usuwasz host_2, który nie został utworzony. Ty chciałbyś usunąć tą deklarację, gdyż jest zbędna, ale tak się nie da. Pamięć została już zarezerwowana na ten obiekt i nie zostanie zwolniona tak długo, jak długo istnieje obiekt klasy, w której jest tworzony.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Slynx » wtorek, 12 kwietnia 2011, 14:00

Blok switch nie jest konstruktorem, ale jak rozumiem to taki skrót myślowy...


No tak. Dla mnie to to samo, bo jeśli coś znajduje się w konstruktorze, to i tak będzie działać tylko wewnątrz niego, chyba, że ma możliwość odwołania do jakiejś globalnej deklaracji.
Mniejsza o szczegóły.

Przeszkadza mi po prostu, że wtedy te deklaracje można wykorzystać jak odwołania. To nie są nowe obiekty klas (host), ale i tak umożliwiają komunikację z pozostałymi klasami.
Więc może po prostu zapytam - można to zrobić inaczej ? Tak by w konstruktorze podawać numer przyporządkowany konstruktorowi danej klasy (czyli jak w switch), by tworzyć obiekt globalny.

I jeszcze coś w ramach sprostowania. Mówisz, że pamięć jest przydzielana. Ile pamięci ? To jest tylko deklaracja typu... a raczej (chyba) tworzenie wskaźnika do klasy. Nie jest tworzony obiekt tej klasy bo nie został użyty konstruktor, ani operator (gc)new. Tutaj coś czuję trochę niepewny grunt ; p
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Cyfrowy Baron » wtorek, 12 kwietnia 2011, 14:59

Slynx napisał(a):I jeszcze coś w ramach sprostowania. Mówisz, że pamięć jest przydzielana. Ile pamięci ? To jest tylko deklaracja typu... a raczej (chyba) tworzenie wskaźnika do klasy. Nie jest tworzony obiekt tej klasy bo nie został użyty konstruktor, ani operator (gc)new. Tutaj coś czuję trochę niepewny grunt ; p


Trochę z tym namieszałem, gdyż deklaracja informuje tylko o obiekcie, a użycie operatora new dopiero rezerwuje pamięć dla obiektu - ile? To chyba zależy do rodzaju zmiennych i obiektów wykorzystywanych przez klasę.

Slynx napisał(a):Więc może po prostu zapytam - można to zrobić inaczej ? Tak by w konstruktorze podawać numer przyporządkowany konstruktorowi danej klasy (czyli jak w switch), by tworzyć obiekt globalny.


Zw switch to powinieneś to robić tak:

KOD cpp:     UKRYJ  
 switch (host)
 {
  case 1:
            this->host_1 = gcnew Mail::Host_1(); // to this jest zbędne
            break;
  case 2:
           this->host_2 = gcnew Mail::Host_2(); // to this jest zbędne
           break;
 ]
delete jest zbędne, przecież konstruktor jest wywoływany tylko raz podczas tworzenia obiektu. Przy takim rozwiązaniu utworzony zostanie tylko jeden obiekt, dla drugiego pozostanie tylko deklaracja. Zmienna host powinna być poprzez konstruktor przekazana do jakiejś zmiennej globalnej by można było w destruktorze, lub innej funkcji zniszczyć właściwy obiekt, czyli coś w stylu:

KOD cpp:     UKRYJ  
// destruktor
switch(host)
{
 case 1:
         delete host_1; // to this jest zbędne
         break;
 case 2:
        delete host_2;
        break;
}
Można by też prościej:

KOD cpp:     UKRYJ  
if(host_1 != NULL) delete host_1;
if(host_2 != NULL) delete host_2;


To chyba powinno zadziałać.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez polymorphism » środa, 13 kwietnia 2011, 10:22

Można by też prościej:
KOD cpp:     UKRYJ  
if(host_1 != NULL) delete host_1;
if(host_2 != NULL) delete host_2;

Albo jeszcze prościej:
KOD cpp:     UKRYJ  
delete host_1;
delete host_2;
 

Według standardu C++ możesz bez obawy podać NULLa operatorowi delete.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2157
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Cyfrowy Baron » czwartek, 14 kwietnia 2011, 09:55

I to cofa nas do punktu wyjścia, gdyż niszczenie obiektu wewnątrz bloku catch nie powinno wywoływać żadnego błędu, no chyba, że w C++/CLI jest inaczej..
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4719
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Slynx » czwartek, 14 kwietnia 2011, 19:33

No to wszystko co podałeś to już miałem. Delete było tylko prototypowo, bo chciałem pozbyć się także deklaracji, no ale tak nie można.
Będzie trzeba po prostu kontrolować to co się robi w kodzie.

Miałem jeszcze dodatkowe pytanie, ale to w sumie nieistotne. Ten cały destruktor chyba w ogóle nie będzie potrzebny.
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Re: niszczenie "obiektów" klasy wewnątrz konstruktora

Nowy postprzez Slynx » wtorek, 10 maja 2011, 20:20

Ok, odświeżam temat, bo chcę do tego podejść trochę inaczej. Tu żadnego problemu nie ma, wszystko "elegancko" działa.
Tylko.... czy nie ma lepszego sposobu by to zrobić. Spójrzmy raz jeszcze na kod:
KOD cpp:     UKRYJ  
        MailBox::MailBox(mailBox m_box)
                {
                        switch (m_box)
                        {
                        case mailBox::host_1:
                                this->host_mail_ru = gcnew Slanter_Mailboxes::host1();
                                delete this->host_3;
                                delete this->host_2;
                                delete this->host_4;
                                break;
                        case mailBox::host_3:
                                this->host_g_pl = gcnew Slanter_Mailboxes::host3();
                                delete this->host_1;
                                delete this->host_2;
                                delete this->host_4;
                                break;
                        case mailBox::host_2:
                                this->host_o2_pl = gcnew Slanter_Mailboxes::host2();
                                delete this->host_3;
                                delete this->host_1;
                                delete this->host_4;
                                break;
                        case mailBox::host_4:
                                this->host_wp_pl = gcnew Slanter_Mailboxes::host4();
                                delete this->host_3;
                                delete this->host_2;
                                delete this->host_1;
                                break;
                        }
                }


W pliku h,
KOD cpp:     UKRYJ  
       
                        enum class mailBox {host_1, host_2, host_3, host_4} String;
               
                        Mailboxes::host1^ host_1;
                        Mailboxes::host2^ host_2;
                        Mailboxes::host3^ host_3;
                        Mailboxes::host4^ host_4;
               
                        MailBox(mailBox m_box);

 


Jak wygląda wywoływanie

KOD cpp:     UKRYJ  
MailBox^ box = gcnew MailBox(MailBox::mailBox::host_1);
box->host_1->Create(value1, value2);


Zależy mi na jakimś bardziej eleganckim rozwiązaniu, ale nic mi nie wpada do głowy, przede wszystkim, by wywoływanie wyglądało inaczej, np.

KOD cpp:     UKRYJ  
box->Create(val1, val2); // czyli bezpośrednio do hosta podanego w konstruktorze;
//ewentualnie jakaś jednakowa funkcja, np.
box->xxx->Create(val1, val2);


Tu są 4 klasy, ale gdy takich klas nazbiera się więcej zrobi się straszny śmietnik.
Może jest do tego jakiś model, który można by wykorzystać, czy inny klasyczny sposób rozwiązania problemu:/
Klasa jest "jednorazowego użycia", tj. wartość hosta, można przypisać tylko przez konstruktor i pracować już tylko na nim.
Avatar użytkownika
Slynx
Mądrosław
Mądrosław
 
Posty: 350
Dołączył(a): piątek, 17 grudnia 2010, 21:59
Podziękował : 11
Otrzymał podziękowań: 0
System operacyjny: Windows 7 32
Kompilator: Visual C++ 2005; Visual C++ 2008; Visual C++ 2010; Visual C# 2010;
Gadu Gadu: 0
    Windows 7Chrome

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 17 gości

cron