Article View: pl.comp.lang.c
Article #81Re: Parametry operatora new w C++
From: Stanislaw Bochnak
Date: Thu, 16 Oct 1997 00:00
Date: Thu, 16 Oct 1997 00:00
125 lines
4073 bytes
4073 bytes
Jerzy Goca wrote:
>
> Witam!
> Mam 4 pytania dotyczace operatora new w c++:
>
> 1) Czytajac literature dotyczaca c++, w kilku waznych podrecznikach
> przeczytalem o czesto stosowanym w praktyce przeciazaniu operatorow
> new i delete. Niestety przyklady cytowane przy tych okazjach wydawaly
> mi sie raczej malo praktyczne. Wydaje mi sie, ze chyba nie ilustrowaly
> one wlasciwie calego problemu. Czy moglby wypowiedziec sie ktos na ten
> temat?
>
> 2) Zobaczylem ostatnio konstrukcje (Guru of the week #22)
> class T { /* ... */ };
>
> void main()
> {
> T *t1, t2;
> t1=new(&t2) T;
> }
> Prosze o wyjasnienie parametru operatora new.
> Znam deklaracje tego operatora, ale chyba mam niepelne informacje o
> skladni wywolania.
Tutaj jest zastosowana wersja operatora new, ktora umozliwia
umiejscowienie
tworzonego obiektu w zadanym obszarze pamieci. Po new w nawiasach nalezy
podac
adres, tutaj jest to adres obiektu t2.
>
> 3) W niektorych zastosowaniach wygodna jest konstrukcja z jezyka C:
> typedef
> struct arr {
> struct arr *next;
> int n;
> double data[1];
> };
>
> struct arr *alloc(int n) {
> struct arr *p=(struct arr *)malloc(sizeof(arr)+sizeof(double)*(n-1));
> return p;
> }
>
> void destroy(struct arr *p) {
> free(p);
> }
>
> Jak w jezyku C++ napisac konstruktor i destruktor, ktory robi cos
> podobnego, jak funkcja alloc? Czy moze do takich celow przeciaza sie
> operator new i delete ?. Jesli tak to w jaki sposob przekazac mu
> rozmiar?
Przedstawiles powyzej technike 'rozrastajacej sie strutury', gdie
ostatnie
pole 'data' sluzy tylko jako pierwszy bajt wiekszej tablicy. W C++ cos
takiego jest niedozwolone, wlasnie z tego powodu, ze operator new
otrzymuje rozmiar pamieci do zaalokowania, a rozmiar ten jest obliczany
przez kopmilator w czasie kompilacji a nie w czasie wykonania, wobec
czego jest on STALY!!!
Operatory new i delete sa funkcjami statycznymi klasy i zwykle wlasnie
przeciaza sie je w klasie, tak by zapewnic wlasny mechanizm alokacji
obiektow tego typu (i pochodnych).
>
> 4) Czy alokowanie wielu obiektow za pomoca new nie prowadzi
> przypadkiem do nadmiernego "trwonienia" sterty? Czy lepiej jest
> zaalokowac od razu wiekszy "kawal" pamieci dla skladowych obiektu i
> "rozlokowywac" je w konstruktorze. Np. tak:
> class X {
> int n;
> double *u1, *u2, *u3,*u4;
> int *i1, *i2;
> public:
> X(int n);
> ~X();
> /* ... */
> private:
> char *mem;
> };
>
> X::X(int n)
> {
> mem=new char[(sizeof(double)*4+sizeof(int)*2)*n];
> u1=(double*)mem;
> u2=u1+n;
> u3=u2+n;
> u4=u3+n;
> i1=(int*)(u4+n);
> i2=i1+n;
> }
>
> X:~X()
> {
> delete []mem;
> }
Mozna tak zrobic. W takim wlasnie celu przeciaza sie operator new -
aby zapewnic efektywniejsze zarzadzanie pamiecia w sytuacjach,
gdy standardowe nie dziala dostatecznie dobrze. Ale trzeba pamietac, ze
przy alokowaniu
jednego ciaglego bloku pamieci moze byc problem ze znalezieniem
odpowiednio duzego
na stercie!!!
W przykladzie powyzej - lepiej jest uzyc pol typu 'double' zamiast
'double*' -
>
> Czy mozna to zorganizowac podobnie jak funkcja alloc w pkt. 3,
> unikajac pola mem ? Prosze o sugestie dotyczace dobrego i zlego stylu
> w tym zakresie.
Musze powiedziec, ze nie jest to najlepszym pomyslem w C++.
Czasami mozna zyskac na zarzadzaniiu pamiecia, ale mozna tez stracic,
a program jest mniej czytelny.
Pozdrawiam,
SB
Technical Details
Message-ID:
<3445C0B5.3B318A38@microTOOL.com.pl>Path:
mbox-mo1.pugleaf.net!unknown!not-for-mailReferences:
<3443b99a.26041221@news.nask.org.pl>Show Full Headers
Complete Article Headers
From: Stanislaw Bochnak <S.Bo...@microTOOL.com.pl> Subject: Re: Parametry operatora new w C++ Date: 1997/10/16 Message-ID: <3445C0B5.3B318A38@microTOOL.com.pl> X-Deja-AN: 281022949 References: <3443b99a.26041221@news.nask.org.pl> To: Jerzy Goca <jg...@wel.wat.waw.pl> X-Priority: 3 (Normal) Organization: microTOOL Sp. z o.o. Newsgroups: pl.comp.lang.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit