dynamiczne tworzenie formularzy

dział ogólny

Re: dynamiczne tworzenie formularzy

Nowy postprzez banita » poniedziałek, 19 stycznia 2009, 00:25

jesli wskaznik nie ma byc wspoldzielony to juz lepiej napisac wlasna klase opakowujaca wskaznik. auto_ptr nie mozna nawet przekazac do funkcji bo argument wywolania straci waznosc. nie mozna uzyc jako elementu kontenera STL (STLport w ogole nie dopusci do kompilacji takiego kodu). sytuacje pozwalajace uzytkowac wskazniki auto_ptr sa bardzo ograniczone a wlasna klasa opakowujaca moze byc wykozystana wszedzie.
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
Podziękował : 1
Otrzymał podziękowań: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez polymorphism » poniedziałek, 19 stycznia 2009, 00:46

jesli wskaznik nie ma byc wspoldzielony to juz lepiej napisac wlasna klase opakowujaca wskaznik.

Ale po co, jeśli jest już taki w standardzie?

auto_ptr nie mozna nawet przekazac do funkcji bo argument wywolania straci waznosc.

Ale po co ja mam przekazywać obiekt auto_ptr funkcji, jeśli mogę po prostu przekazać wskaźnik? A nawet jeśli, to co stoi na przeszkodzie przekazać go przez referencję?

nie mozna uzyc jako elementu kontenera STL

No nie można, dlatego ktoś wymyślił shared_ptr. O niczym to nie świadczy, a argument jest tego typu co ten, że string jest do dupy, bo nie obsługuje unikodu. Nie ma klas uniwersalnych i o nieograniczonych możliwościach.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
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 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez Cyfrowy Baron » wtorek, 20 stycznia 2009, 10:20

Sprawdziłeś ? U mnie tworzą się nowe formy tak jak w przypadku new.
Kod: Zaznacz cały
  TForm1 *Form12;
  Application->CreateForm(__classid(TForm1), &Form12);
  Form12->Show();


Rozważałem tylko taką sytuację:

Kod: Zaznacz cały
Application->CreateForm(__classid(TForm2), &Form2);
Form2->Show();


i w tym wypadku nie dało się oczywiście zrobić tak:

Kod: Zaznacz cały
Application->CreateForm(__classid(TForm2), &MyForm);
MyForm->Show();


ale masz rację, nie wiem czemu mi to umknęło.
Pracuję ostatnio po nocach, więc nie myślę już nazbyt logicznie.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
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
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez banita » poniedziałek, 20 lipca 2009, 19:24

mam pytanie dotyczac tworzenia formularzy wiec dopisze je tutaj.
budujemy fomratke(wizualnie), jakies buttony, radio itp...
usuwamy formularz z autocreate, w razie potrzeby sami alokujemy i zwalniamy pamiec.

wszystkie komponenty znajdujace sie w klasie formularza w sekcji __published, czyli te ktore kladziemy na forme wizualnie sa alokowane i zwalniane bez naszej wiedzy. nie musimy ich alokowac w konstruktorze klasy(formatki) mimo iz sama formatke tworzymy dynamicznie podczas dzialania aplikacji. tak samo z zamykanie formatki. wlasciwosci z sekcji __published sa zwalniane bez naszej wiedzy.

jesli w klasie np w sekcji private dodamy int* czy jakis inny wskaznik to w konstruktorze formatki musimy go alokowac a przy zamykaniu zwalniac. to tyle slowem wstepu.

pytanie jest takie: jaka jest kolejnosc alokacji tych elementow w klasie. czy najpierw sa alokowane i twozone te z sekcji __published czy te ktore dodamy w sekcjach private badz public?

co dzieje sie w sytuacji gdy w ciele konstruktora mamy operacje ktora moze wyrzucic wyjatek?
takiego wyjatku nie powinno sie lapac w ciele konstruktora(chyba ze zwalniamy pamiec i propagujemy wyjatek na zewnatrz) tylko w miejscu gdzie tworzymy obiekt.

przyklad:
klasa formy - XForm, tworzona dynamicznie.
w konstruktorze klasy moze poleciec wyjatek.

try
{
XForm* frm = new XForm(...); < ---- leci wyjatek
}
catch(...)
{
}

jesli obiekty z sekcji __published sa alokowane najpierw a w ciele konstruktora poleci wyjatek to co sie dzieje z ta pamiecia?
destruktor nie jest wywolywany wiec nie ma kiedy jej zwolnic. w jaki sposob C++Builder rozwiazuje ten problem(a moze nie rozwaizuje?)?
oczywiscie mozemy zrezygnowac z wizualnego tworzenia formularza i napisac wlasna klase bez sekcji __published i w ten sposob miec pelna kontrole na alokowaniem i zwalnianiem pamieci ale skoro tworcy srodowiska wprowadzili taki mechanizm to chyba mieli ku temu powody.

a moze w sytuacji gdy formularz zawiera sekcje __published nie mozna propagowac wyjatku na zewnatrz podczas konstrukcji formularza? tyle ze to lekko godzi w obiektowy "styl" obslugi i zarzadzania sytuacjami wyjatkowymi.
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
Podziękował : 1
Otrzymał podziękowań: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez Cyfrowy Baron » wtorek, 21 lipca 2009, 11:26

Nie znam chyba odpowiedzi na Twoje pytanie, co się jednak tyczy zwalniania pamięci, to wydaje mi się, że w przypadku prawidłowego zamknięcia dynamicznego okna, wystarczy umieścić w zdarzeniu OnClose tegoż formularza:

Kod: Zaznacz cały
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
Action = caFeee;
}
//---------------------------------------------------------------------------


► TColseAction 


Co się jednak tyczy Twojego przykładu, to w przypadku dynamicznego wywołania okna modalnego, problem sam się chyba rozwiąże:

Kod: Zaznacz cały
    Form2 = new TForm2(Application);
    Form2->ShowModal();
    delete Form2;


Problem pojawia się jednak przy niemodalnym oknie, może takie rozwiązanie:
Kod: Zaznacz cały
    Form2 = new TForm2(Application);
    Form2->Show();
    if(!Form2->Visible) delete Form2;


Wygląda to jednak (delikatnie rzecz biorąc) niezbyt przekonująco. Wydaje mi się że rozwiązaniem problemu może być funkcja:

Application->ControlDestroyed(TControl *Control);

która to powiadamia program, że obiekt (parametr) został zniszczony. Nie znalazłem nic więcej na ten temat, więc nie jestem pewien jak tego używać.

Tak więc jak napisałem na wstępie nie znam odpowiedzi, tylko tak sobie kombinuję. Wydaje mi się jednak, że najpierw w pamięci alokowany jest formularz a dopiero potem obiekty które się na nim znajdują, więc jeżeli formularz nie zostanie w wyniku jakiegoś wyjątku utworzony, to nie zostaną utworzone również znajdujące się na nim obiekty. Jeżeli z jakiegoś powodu dojdzie do sytuacji gdy formularz zostanie alokowany razem z obiektami a następnie wystąpi wyjątek to chyba system (WinXP) sam zwolni pamięć.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
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
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez polymorphism » wtorek, 21 lipca 2009, 12:52

jaka jest kolejnosc alokacji tych elementow w klasie. czy najpierw sa alokowane i twozone te z sekcji __published czy te ktore dodamy w sekcjach private badz public?

Z tego co pamiętam, to w konstruktorze był dostęp* do obiektów "stworzonych" wizualnie. Opcja pierwsza wydaje się bardzo prawdopodobna (i logiczna).

jesli obiekty z sekcji __published sa alokowane najpierw a w ciele konstruktora poleci wyjatek to co sie dzieje z ta pamiecia?

Prawdopodobnie nic się nie dzieje, jest wyciek. Choć nie można wykluczyć, że VCL (lub kompilator) ma zaimplementowany jakiś mechanizm zarządzania pamięcią obiektów tworzonych wizualnie i przy zwijaniu stosu obiekty są automatycznie usuwane.

_____________________
*) w sensie odwoływania się do poprawnie skonstruowanych obiektów.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
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 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez banita » wtorek, 21 lipca 2009, 12:54

zakladajac taki przyklad:
mamy klase X (zwykla klasa) i konstruktor:
X::X()
{
a = new int;
b = new double;
jakas_funkcja(); <----- tu leci wyjatek
}

w tym przykladzie jesli podczas wywolania tej funkcji poleci wyjatek to pamiec po 'a' i 'b' nigdy nie zostanie zwolniona.
w momencie wejscia do konstruktora, wszystkie skladniki klasy juz istnieje, mozemy jedynie je modyfikowac badz przydzielac im pamiec.
sprawa jest prosta jesli mowimy o klasach zgodnych ze standardem c++.
formularze borlandowskie takie nie sa. wydaje mi sie iz najpier twozone sa wszystkei obiekty z sekcji __published, chocby dlatego ze w samym ciele konstruktora mozemy im juz ustawiac wlasciwosci.
wiec jesli konstruktor pusci wyjatek, czyli caly obiekt formularza nie jest utwozony, nie jest tez wywolywany jego destruktor.
z drugiej strony programista nie ma nad tym kontroli wiec moze tworcy srodowiska jakos to rozwiazali?.
to wazna kwestia poniewaz jesli ta pamiec jest tracona to wiadomo ze nie mozna wypuscic na zewnatrza wyjatku a jesli jakich mechanizm ja zwalnia to wtedy mozemy obslugiwac wyjatki jak pan bog nakazal.
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
Podziękował : 1
Otrzymał podziękowań: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez Witold » wtorek, 21 lipca 2009, 23:55

banita napisał(a):jesli obiekty z sekcji __published sa alokowane najpierw a w ciele konstruktora poleci wyjatek to co sie dzieje z ta pamiecia?


W sekcji __published są tyko wskaźniki. Z moich testów (BCB6) wynika że dla komponentów które mają znaleźć się na formie, gdy zostanie rzucony wyjątek z konstruktora formy zostaną wywołane destruktory. Wyniki prymitywnego testu z "gadającymi" konstruktorami i destruktorami.

Test1:
konstruktor TTest0
konstruktor TTest1
konstruktor TTest2
konstruktor TfrmTest (z ciała konst.)
Leci wyjątek z konstruktora TfrmTest!!!!
destruktor TTest2
destruktor TTest1
destruktor TTest0

Tak samo stanie się gdy jeden z tych komponentów , rzuci wyjątek z swojego konstruktora, dla tych które utworzone poprawnie – zostaną wywołane destruktory.

test2:
konstruktor TTest1
konstruktor TTest2
wyjątek z konstruktora TTest2
destruktor TTest1


TTest0 , TTest1, TTest2 – to komponenty z formy.
TfrmTest – forma tworzona przez new.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez banita » czwartek, 23 lipca 2009, 21:11

w jaki sposob przeprowadziles ten test? twozyles w tym celu komponenty z gadajacymi konstruktorami i destruktorami?
w bcb2007 nie moge nic umiescic w sekcji __published jesli to fizycznie nie jest polozone na formie.
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
Podziękował : 1
Otrzymał podziękowań: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez Witold » czwartek, 23 lipca 2009, 23:22

banita napisał(a):twozyles w tym celu komponenty z gadajacymi konstruktorami i destruktorami?


tak
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
Podziękował : 1
Otrzymał podziękowań: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez usermaw » niedziela, 20 września 2009, 13:16

Cyfrowy Baron napisał(a):operator delete zwalnia pamięć. Przypisanie wartości 0 do tego co już zero zawiera wydaje mi się zbędne.


Jesli pod jednym przyciskiem chce miec pokazywanie i ukrywanie formy, zerowanie ma sens. dla dynamicznych form.

if(Form2==0)
{
Formularz
}
else
{
delete Form2;
Forma2=0; //bez tego mi nie działa, tzn wywali sie po ponownym wywolaniu. Delete chyba nie przypisuje 0 z automatu.
}
Avatar użytkownika
usermaw
Homos antropiczny
Homos antropiczny
 
Posty: 55
Dołączył(a): piątek, 2 stycznia 2009, 20:43
Podziękował : 2
Otrzymał podziękowań: 0
    NieznanyNieznana

Re: dynamiczne tworzenie formularzy

Nowy postprzez banita » niedziela, 20 września 2009, 16:43

mozna skonzystac z funkcji FreeAndNil ktora zwalnia pamiec i przypisuje NULL, warunek jest taki ze argument wywolania musi byc pochodny do TObject
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
Podziękował : 1
Otrzymał podziękowań: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Poprzednia 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 7 gości