Declararea unui obiect de tip pointer?

Intrebari despre limbajul C++, standardul C++, STL, OOP in C++ sau alte subiecte nelegate de VisualC++
Post Reply
Abi_Moonbow
Junior
Junior
Posts: 15
Joined: 17 Apr 2013, 11:36
Judet: Argeş

Declararea unui obiect de tip pointer?

Post by Abi_Moonbow » 20 Apr 2013, 21:17

Sunt in clasa a 12-a si nu am facut la scoala POO, dar m-am apucat sa invat de unul singur. Am invatat in mare clasele, am si lucrat cu ele, dar am o intrebare:
Care este diferenta dintre a declara un obiect de tip pointer( nume_clasa *obiect ) sau de al declara normal( nume_clasa obiect ) ?
Stiu ca se metodele se apeleaza in mod diferit( pointerul cu -> ), dar m-ar interesa din punct de vadere al memoriei, sau ce urmari are declararea obictului de tip pointer...

Multumesc!



George92
Junior
Junior
Posts: 16
Joined: 13 Apr 2013, 00:37
Judet: Dolj

Re: Declararea unui obiect de tip pointer?

Post by George92 » 21 Apr 2013, 00:12

Sunt foarte importanti in special in metodele de upcasting si downcasting, poti face ceva de genu ClasaBaza* Obiect = new ClasaDerivata(); De asemenea trebuie sa te asiguri ca eliberezi memoria cand termini cu obiectul respectiv folosind operatorul delete deoarece memoria se aloca dinamic.

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: Declararea unui obiect de tip pointer?

Post by Silviu Ardelean » 21 Apr 2013, 02:18

nume_clasa obiect;
  • - obiect creeat pe stiva
    - are durata de viata cat timp "obiect" e in scopul declaratiei sale si dispare cand pierde scopul (ex. iesi din functia/metoda in care l-ai declarat).
nume_clasa *obiect;
  • - poate fi pointer la: un obiect de pe heap/stack, la nimic (neinitializat), initializat cu 0/NULL/nullptr.
    - pointerul (adresa) se poate schimba printr-o simpla asignare la alt obiect de pe heap sau chiar la adresa unui obiect de pe stiva.
    - un obiect indicat de un pointer si care s-a creeat pe heap(new) nu e eliberat decat la cerere expresa cu delete/free(daca folosesti malloc()). Cand vorbim de alocare pe heap nu mai tine de scopul declaratiei. Neeliberarea memoriei (de ex. s-a schimbat adresa spre care pointa initial si n-o mai ai sau uiti sa stergi obiectul de pe heap) duce la memory leaks.

Cam atat la astfel de ore...

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Declararea unui obiect de tip pointer?

Post by Ovidiu Cucu » 21 Apr 2013, 10:14

Pe scurt si in principiu: un pointer este o variabila care tine o adresa. Punct si de la captat.
Mai departe, cum si de ce folosim pointeri se poate discuta si o zi intreaga.

Raspunzand strict la intrebarea ta, asa cum ai formulat-o:
Care este diferenta dintre a declara un obiect de tip pointer( nume_clasa *obiect ) sau de al declara normal( nume_clasa obiect ) ?
[...] m-ar interesa din punct de vadere al memoriei, sau ce urmari are declararea obictului de tip pointer...
Din punct de vedere al (n.r. utilizarii) memoriei, in primul caz se declara un pointer la tipul nume_clasa si va ocupa cat ocupa orice pointer in implementarea data (4 bytes, 8 bytes sau in general sizeof(T*)). In cel de-al doilea caz se construieste un obiect tip nume_clasa care va ocupa in memorie sizeof(nume_clasa).
Ca sa te lamuresti ruleaza urmatorul programel simplu:

Code: Select all

#include <iostream>

class CFoo
{
   int m;
   double d[100];
};

int main()
{
   CFoo obj;
   CFoo* ptr;

   std::cout << "obj ocupa in memorie " << sizeof(CFoo) << " bytes.\n"
      << "ptr ocupa in memorie " << sizeof(CFoo*) << " bytes." << std::endl;

}
Asta voiai sa afli? Daca nu, te rog detaliaza, eventual da exemple concrete si discutam.
Cum an afirmat la inceput, sunt multe de discutat la pointeri.

Abi_Moonbow
Junior
Junior
Posts: 15
Joined: 17 Apr 2013, 11:36
Judet: Argeş

Re: Declararea unui obiect de tip pointer?

Post by Abi_Moonbow » 21 Apr 2013, 13:48

In legatura cu memoria pe care o folosesc cele doua declarari acum imi este clar.
Inclin sa cred ca e mai bine sa declar o clasa de tip pointer, dar sa ii eliberez memoria cand am terminat de lucrat cu ea. Corect? Totusi care sunt avantajele pe care le ofera declararea unei clase declarate nume_clasa obiect?

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: Declararea unui obiect de tip pointer?

Post by Silviu Ardelean » 21 Apr 2013, 14:57

Avantajele si dezavantajele le poti deduce din enumerarea mea de mai sus si difera de contextul declararii si folosirii obiectelor.
Pe cat posibil, recomandarea mea ar fi sa folosesti declaratii clasice fara pointeri. Scapi de grija eliberarii memoriei si folosesti stiva care e mai "rapida" decat heap-ul caci la creeare, intern, are loc doar o mutare a pointerului pe stiva.

User avatar
bu7ch3r
Membru++
Membru++
Posts: 326
Joined: 17 May 2011, 15:17
Judet: Iaşi
Location: Sofia
Contact:

Re: Declararea unui obiect de tip pointer?

Post by bu7ch3r » 21 Apr 2013, 17:08

Nu prea e bine sa aloci obiecte cu malloc pentru ca nu se apeleaza constructorul - se aloca doar memorie si atat.
Doar daca urmaresti sa apelezi new mai tarziu: ceva de genul: ClasaMea * obiect = new (pointerReturnat_de_malloc) ClasaMea(). Apoi o sa trebuiasca sa apelezi explicit destructorul inainte de free(daca este cazul:)).
Pana acum n-am vazut asa ceva, dar cine stie :-??

New aloca memorie si iti si apeleaza constructorul.
Cu stima,
Lupu Claudiu

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Declararea unui obiect de tip pointer?

Post by Ovidiu Cucu » 21 Apr 2013, 23:20

Abi_Moonbow wrote:[...]
Inclin sa cred ca e mai bine sa declar o clasa de tip pointer, dar sa ii eliberez memoria cand am terminat de lucrat cu ea. Corect? [...]
Nu, cel putin exprimarea nu este corecta.
Ceva de genul...

Code: Select all

nume_clasa* ptr;
...nu declara o "clasa tip pointer" (nu exista asa ceva in C++) ci un pointer la tipul nume_clasa.

Ar fi bine sa iei o carte sau un manual serios si sa te pui la punct cu conceptele de baza ale limbajului.
Doar ca sa-ti dau un punct de plecare, conform standardului tipurile in C++ sunt:
  • Tipuri fundamentale (fundamental types)
    • caracter (character types) - char, signed char si unsigned char;
    • intregi cu semn (signed integer types) - signed char, short int, int, si long int;
    • intregi fara semn (unsigned integer types) - unsigned char, unsigned short int, unsigned int, si unsigned long int;
    • boolean - bool (cu valorile true si false);
    • tipuri reale (floating point types) - float, double si long double;
    • void.
  • Tipuri compuse (compound types)
    • siruri (arrays);
    • functii (functions);
    • pointeri (pointers) la void, la obiecte sau la functii;
    • referinte (references);
    • clase (classes) - sunt structuri de date custom (class, struct sau union);
    • enumerari (enumerations) - contin un set de nume reprezentand valori constante;
    • pointeri la functii membre nestatice.
Alte clasificari poti gasi, de exemplu, si in "The C++ Programming Language" a lui Bjarne Stroustrup.
C++ has a set of fundamental types corresponding to the most common basic storage units of a computer and the most common ways of using them to hold data:
§4.2 A Boolean type (bool)
§4.3 Character types (such as char)
§4.4 Integer types (such as int)
§4.5 Floating point types (such as double)
In addition, a user can define
§4.8 Enumeration types for representing specific sets of values (enum)
There also is
§4.7 A type, void, used to signify the absence of information
From these types, we can construct other types:
§5.1 Pointer types (such as int*)
§5.2 Array types (such as char[])
§5.5 Reference types (such as double &)
§5.7 Data structures and classes (Chapter 10)

The Boolean, character, and integer types are collectively called integral types.
The integral and floating point types are collectively called arithmetic types.
Enumerations and classes (Chapter 10) are called user defined types because they must be defined by users rather than being available for use without previous declaration, the way fundamental types are.
In contrast, other types are called builtin types.
Zic sa iei frumusel si sa-l pritocesti pe fiecare in parte.
Sa intelegi in primul rand ca pointer este un tip distinct care in principiu reprezinta o adresa a unui alt tip (pointeaza la un alt tip).
Exemple:
  • void* - pointer la void, cu alte cuvinte pointeaza la un tip nespecificat;
  • int* - pointer la tipul int;
  • int** - pointer la tipul pointer la int (int*);
  • CFoo* - pointer la tipul CFoo, unde CFoo este un tip clasa (class, struct sau union);
  • int(*pfn)(float) - pointer la o functie.
De ce folosim si/sau la ce sunt buni pointerii?
Facand analogie cu teorema lui Pitagora par ar fi "puntea măgarilor" in C si C++... :)
O sa revin mai tarziu sau maine, cu ceva exemple.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Declararea unui obiect de tip pointer?

Post by Ovidiu Cucu » 22 Apr 2013, 09:26

Deci, ce ce folosim pointeri?
  • Transmiterea optima a parametrilor.
    Sa zicem ca transmitem "prin valoare" (by value) un obiect de dimensiuni mari.

    Code: Select all

    class CFoo
    {
       int m;
       double d[100];
    };
    
    void f1(CFoo foo)
    {
       //...
    }
    In exemplul dat, la apelul functiei f1 se pun pe stiva sute de bytes (sizeof(CFoo)).
    Daca insa folosesc pointer...

    Code: Select all

    void f2(CFoo* pFoo)
    {
       //...
    }
    ...se pun pe stiva doar sizeof(CFoo*), adica numarul de bytes ocupat de un pointer (de ordinul a catorva bytes, depinzand de implementare).
    In plus, in cazul lui f1 se face o copiere a obiectului pasat, ceea ce nu se intampla si la f2, careia i-am pasat un pointer.
    Deci, folsind pointer am castig de performanta atat din punct de vedere al memoriei utilizate cat si al vitezei de executie.
  • Acelasi motiv ca la punctul #1 se aplica si la valoarea de return din functie.
  • Vrem ca o valoare care se modifica in functia apelata sa se regaseasca dupa intoarcerea din acea functie.
    Exemplu:

    Code: Select all

    void f3(int n)
    {
       n += 100;
    }
       //...
       int n = 1;
       f3(n); // parametru transmis prin valoare
       std::cout << "n = " << n; // valoarea afisata este 1.
    

    Code: Select all

    void f4(int* n)
    {
       n += 100;
    }
       //...
       int n = 1;
       f4(&n); // transmit pointer
       std::cout << "n = " << n; // valoarea afisata este 101.
    
  • Parcurgerea sirurilor (arrays) folosind aritmetica pointerilor.
    Exemplu

    Code: Select all

       char txt[] = "ala bala portocala";
       // ...
       char* p = txt;
       while(*p)
       {
          if(*p == 'a')
          {
             *p = 'u';
          }
          p++; // trec la elementul urmator incrementand pointerul p
       }
    De altfel, intre array-uri si pointeri exista o stransa legatura, insa nu intru aici in amanunte.
  • Functiile C pentru alocare dinamica (malloc, calloc etc) intorc... oare ce oare? O adresa de memorie. Sau vorbind in termenii limbajului C/C++... un pointer. In continuare se foloseste acel pointer, pana la dealocare (cu free).
    La fel se intampla in limbajul C++ cu operatorii new si delete.
  • In C/C++ NU exita un tip built-in pentru texte/stringuri. Strigurile se tin in siruri de caractere iar pentru a lucra ce ele folosim... pointeri.
  • In C++ se folosesc pointeri pentru apelul functiilor dintr-o clasa derivata folosind pointeri la o clasa de baza. De altfel, tot mecanismul de functii virtuale din C++ este implementat cu pointeri.
  • Ar mai fi... amintesc doar despre functiile callback, transmiterea parametrilor sau a valorii de return pentru un tip nespecificat (void*), etc.


Pointerii sunt folositi pe scara larga mai ales in C. In C++ exista un tip nou, referinta, care poate fi folosit pentru unele dintre motivele pe care le-am enumerat mai sus.
Retine insa din start ca pointerii si referintele sunt tipuri diferite (vezi clasificarea din postul precedent). Iarasi, nu intru in amanunte.
Oricum, nu poti inlocui complet pointerii cu referintele in C++. In plus, daca folosesti biblioteci cum ar fi de exemplu Windows API, care au interfata C, trebuie sa "mananci pointeri pe paine". :)

E clar pana aici de ce folosim pointeri?
Revenind la intrebarea initiala (reformulata un pic), "Care sunt avantajele declaratiei nume_clasa obiect versus nume_clasa* object?".
Pai, intrebarea nu prea are sens. Oricum, pana la urma urmei lucrez cu obiecte, deci trebiuie sa am undeva declarat + definit un obiect de tip "nume_clasa".
Pointerii ii folosesc pentru acces (indirect) la acel obiect. De ce? Vezi motivele de mai sus.

Ok sau necesita alte lamuriri?

User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Declararea unui obiect de tip pointer?

Post by Marius Bancila » 22 Apr 2013, 11:01

Abi_Moonbow wrote:In legatura cu memoria pe care o folosesc cele doua declarari acum imi este clar.
Inclin sa cred ca e mai bine sa declar o clasa de tip pointer, dar sa ii eliberez memoria cand am terminat de lucrat cu ea. Corect? Totusi care sunt avantajele pe care le ofera declararea unei clase declarate nume_clasa obiect?
Banuiesc ca o sa reiau ce au zis altii (n-am citit tot), dar crearea obiectelor pe stiva are avantajul managementului de memorie automat (alocare si dealocare). Obiectele se distrug cand ies din scop. Cand instantiezi obiecte pe heap, trebuie sa te ocupi explicit de durata de viata a obiectului, de alocarea si eliberarea memoriei. Nu e complicat, dar e mai usor de facut greseli, din care cauza mediile managed (Java, .NET) sunt atat de populare, intrucat au garbage collectors care se ocupa de eliberarea memoriei pentru obiectele care nu mai sunt referite din program. Se poate face si in C++ eliberarea automata de memorie pentru obiectele de pe stiva, dar trebuie sa folosesti "pointeri destepti" shared_ptr si unique_ptr.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Declararea unui obiect de tip pointer?

Post by Ovidiu Cucu » 22 Apr 2013, 13:24

Marius Bancila wrote:[...] n-am citit tot [...]
Sigur, nu. ;)
Cred ca asta-i o boala printre programmerii de C++. Cum pune unul o problema pointer vs. object, cum sar o suta in sus cu heap vs. stack... :)
Problema initiala, reformuland si eliminand unele greseli de termeni, suna cam asa:

Care este deosebirea (in special referindu-ne la utilizarea memoriei) intre declaratia unui obiect si a unui pointer la un obiect?
De exemplu, intre

Code: Select all

   nume_clasa obj;
si

Code: Select all

   nume_clasa* ptr;
[/i]

Nu se spune absolut deloc ce valoare va primi in continuare acel pointer si/sau unde anume va pointa acel pointer (in heap, pe stiva, la NULL sau la un carcalac).
NU este obligatoriu ca un pointer sa arate catre ceva alocat dinamic in heap.
Adica, poate sa fie ceva de genul

Code: Select all

   nume_clasa* ptr = new nume_clasa;
pointand astfel la un obiect alocat in heap, dar poate la fel de bine sa fie si

Code: Select all

   nume_clasa* ptr = &obj;
unde obj este bine-mersi un obiect de pe stiva, sau

Code: Select all

   nume_clasa* ptr = NULL;
sau, asa cum este declarat in OP, e "carcalac", "garbage", pointer neinitializat, zi-i cum vrei.

Eu am incercat, ca raspuns la problema asa cum a fost formulata destul de vag, sa lamuresc in primul rand ce diferentiaza un pointer de alte tipuri, la ce sunt buni si cum se folosesc.
Atata timp cat aceste lucruri de acest gen nu sunt bine intelese, geaba ne aruncam in heap sau sarim peste stiva. :)

User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Declararea unui obiect de tip pointer?

Post by Marius Bancila » 23 Apr 2013, 09:50

Ovidiu Cucu wrote:
Marius Bancila wrote:[...] n-am citit tot [...]
Sigur, nu. ;)
Cred ca asta-i o boala printre programmerii de C++.
Nu e o boala, doar ca tu cand te pornesti nu te mai opresti. Iti place sa scri volume, si n-am avut timp sa citesc tot.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Declararea unui obiect de tip pointer?

Post by Ovidiu Cucu » 23 Apr 2013, 11:10

[off-topic]
Marius Bancila wrote:
Ovidiu Cucu wrote:
Marius Bancila wrote:[...] n-am citit tot [...]
Sigur, nu. ;)
Cred ca asta-i o boala printre programmerii de C++.
Nu e o boala, doar ca tu cand te pornesti nu te mai opresti. Iti place sa scri volume, si n-am avut timp sa citesc tot.
"Cine n-are programatori batrani, sa-si cumpere!". :)
Ma refeream la sindromul "Heap 'n stack" ca reactie exagerata la stimuli gen pointeri si obiecte. :D
Si nu, n-am criticat nici un raspuns. Am facut observatia la modul general.

Abi_Moonbow
Junior
Junior
Posts: 15
Joined: 17 Apr 2013, 11:36
Judet: Argeş

Re: Declararea unui obiect de tip pointer?

Post by Abi_Moonbow » 23 Apr 2013, 19:17

Va multumesc tuturor pentru raspuns! Imi sunt mai clare acum declaratia unui obiect sau a unui pointer catre un obiect. Cat de curand o sa iau din nou cartea despre c/c++ pentru a reciti informatiile despre pointeri :))

Post Reply