CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Konstruktor - problem z poprawnym użyciem :/

Konstruktor - problem z poprawnym użyciem :/

dział ogólny

Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez Slynx » wtorek, 1 lutego 2011, 15:35

Mam pewien kod, konkretnie konstruktor dla pewnej klasy:

KOD cpp:     UKRYJ  
                M::M( const string &osc, const  string &cos1, const  string &cos2)
                        :osc_(osc), cos1_(cos1), cos1_(cos1)
                {
                        Klasa1 *obiekt1 = new Klasa1();
                }
 

To działa teoretycznie dobrze. Kompilator akceptuje, bo kod poprawny, ale obiekt1, jest widoczny tylko wewnątrz.
Dlaczego musi być ? Klasa1 jest klasą inicjalizacji połączenia, więc dla każdego nowego obiektu M powinno być zainicjowane połączenie.
Może trochę niejasne ; p
Konstruktor dla tej klasy musi być wywołany, więc uznałem, że konstruktor da pewność stworzenia unikalnego połączenia (Klasa1).
Kolejne funkcje klasy M wykorzystują metody Klasy1, więc obiekt1 musi być dostępny.

Jeśli ktoś ma inny sposób na coś takiego to...
Ale wolałbym żeby to zostało w konstruktorze, tak jest chyba bezpieczniej.
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 7Firefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez polymorphism » wtorek, 1 lutego 2011, 16:00

Kompilator akceptuje, bo kod poprawny, ale obiekt1, jest widoczny tylko wewnątrz.

No a gdzie ma być jeszcze widoczny, jeśli jest zdefiniowany lokalnie?!

Podstawy C++ (i nie tylko) się kłaniają! Poczytaj sobie o klasach, definiowaniu jej pól (składowych).
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
    Windows XPFirefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez Cyfrowy Baron » wtorek, 1 lutego 2011, 16:27

Gwoli wyjaśnienia, jeżeli coś ma być metodą lub obiektem danej klasy, to musi być zadeklarowane w pliku nagłówkowym w sekcji private lub public i w C++ wyglądałoby to tak:

plik nagłówkowy Unit1.h
KOD cpp:     UKRYJ  
private:        // User declarations
        Klasa1 *obiekt1;


plik źródłowy Unit1.cpp
KOD cpp:     UKRYJ  
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
  obiekt1 = new Klasa1();}


Tak zdefiniowany obiekt staje się elementem klasy i może być używany w obrębie całej klasy. Obiekty tworzone lokalnie, tak jak ty zrobiłeś istnieją tylko wewnątrz funkcji w której zostały utworzone. Dodatkowo masz wyciek pamięci, gdyż przed wyjściem z funkcji nie zniszczyłeś obiektu, lecz go porzuciłeś.
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
    Windows XPFirefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez polymorphism » wtorek, 1 lutego 2011, 17:49

Gwoli uzupełnienia. Jeśli tworzysz obiekt w ten sposób, czyli dynamicznie, musisz/powinieneś go usunąć w destruktorze klasy M. Możesz oczywiście użyć inteligentnego wskaźnika, który uwolni Cię od tego obowiązku:
KOD cpp:     UKRYJ  
private:
        std::auto_ptr<Klasa1> obiekt_;
        ...


M::M( const string &osc, const  string &cos1, const  string &cos2)
                        : osc_(osc), cos1_(cos1), cos1_(cos1)
{
        obiekt_.reset(new Klasa1());
}


(...) to musi być zadeklarowane w pliku nagłówkowym w sekcji private lub public ...

... lub protected - to tak dla dopełnienia całości ;)
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
    Windows XPFirefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez Slynx » środa, 2 lutego 2011, 03:24

Więc nie widzę żadnego sensu używania konstruktora. Równie dobrze wszystko to można zrobić w funkcji inicjalizujacej....

W takim razie jak to umieścić by każdorazowe stworzenie obiektu tej klasy powodowało - tak samo - utworzenie obiektu Klasy1, tylko dla dla danego obiektu klasy M.
Chodzi mi o to, żeby nie próbował przy kilku obiektach klasy M pracować cały czas na tym samym obiekcie klasy Klasa1.
Muszę mieć pewność co do tego, bo potem może być problem ze zdiagnozowaniem problemu. Spory problem.

Gwoli wyjaśnienia, jeżeli coś ma być metodą lub obiektem danej klasy, to musi być zadeklarowane w pliku nagłówkowym w sekcji private lub public i w C++ wyglądałoby to tak:

plik nagłówkowy Unit1.h
KOD cpp: � UKRYJ �
KOD cpp: � POKAŻ �
private: // User declarations
Klasa1 *obiekt1;


plik źródłowy Unit1.cpp
KOD cpp: � UKRYJ �
KOD cpp: � POKAŻ �
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
obiekt1 = new Klasa1();}


Tak zdefiniowany obiekt staje się elementem klasy i może być używany w obrębie całej klasy. Obiekty tworzone lokalnie, tak jak ty zrobiłeś istnieją tylko wewnątrz funkcji w której zostały utworzone. Dodatkowo masz wyciek pamięci, gdyż przed wyjściem z funkcji nie zniszczyłeś obiektu, lecz go porzuciłeś.


Tyle to ja wiem, konstruktor, destruktor, zasięg zmiennych (lub też długość życia zmiennych)...
Tutaj też tworzysz obiekt1. Inna kwestia, że jak tak robiłem to chyba domagał się żeby był statyczny (choć pewien nie jestem co on tam wypisał w błędzie), ale to co tworzysz jest tworzone jednorazowo, a nie unikalnie dla każdego obiektu tej klasy(M)... przynajmniej tak to wcześniej rozumowałem.


Gwoli uzupełnienia. Jeśli tworzysz obiekt w ten sposób, czyli dynamicznie, musisz/powinieneś go usunąć w destruktorze klasy M.

To akurat był kod na szybko, więc o to nie dbałem.

Inna kwestia, że teraz piszę w natywnym c++, więc samo przejście z gcnew na new, zrzuca na mnie obowiązek kontrolowania tego co stworzę (jak to dobrze gdy po Tobie sprzątają), jednak z tym sobie poradzę. Czasami może będzie problem z ustaleniem kiedy tak na prawdę obiektu się pozbyć, z racji, że nie będzie wiadomo czy się jeszcze przyda, więc pewnie większość zostanie w pamięci... no cóż, to już moje zmartwienie ; 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 7Firefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez polymorphism » środa, 2 lutego 2011, 12:07

Więc nie widzę żadnego sensu używania konstruktora.

Jak nie widzisz sensu, jeśli za chwilę pytasz:
W takim razie jak to umieścić by każdorazowe stworzenie obiektu tej klasy powodowało - tak samo - utworzenie obiektu Klasy1, tylko dla dla danego obiektu klasy M.

No właśnie po to jest konstruktor, żebyś mógł zainicjalizować pola klasy przy jej tworzeniu - w tym przypadku stworzyć obiekt klasy Klasa1!

Chodzi mi o to, żeby nie próbował przy kilku obiektach klasy M pracować cały czas na tym samym obiekcie klasy Klasa1.

Ech :twisted: Jeśli zdefiniujesz wskaźnik jako niestatyczną składową klasy, to każda instancja tej klasy będzie miała swoją własną wersję tego wskaźnika, a tym samym własną instancję obiektu klasy Klasa1. Czy już rozumiesz?

Dla jasności:
KOD cpp:     UKRYJ  
class M
{
private:
        std::auto_ptr<Klasa1> obiekt_;
        ...
};


Naprawdę, zajrzyj do jakiejś książki od C++, tam wszystko będziesz miał ładnie opisane.
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
    Windows XPFirefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez Cyfrowy Baron » środa, 2 lutego 2011, 12:57

Ja tak do końca to już nie rozumiem. Potrzebujesz wielu obiektów tej samej klasy? Jeżeli tak, to możesz tak jak proponuje polymorphism, ale możesz też posłużyć się wektorem:

plik nagłówkowy Unit1.h
KOD cpp:     UKRYJ  
private:
        vector<Klasa1*> obiekt;


plik źródłowy Unit1.cpp:
KOD cpp:     UKRYJ  
obiekt.push_back(new Klasa1());


Podobny problem został omówiony w tym wątku: http://programowanie.cal.pl/forum/viewtopic.php?f=2&t=1136&p=7805&#p7804
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
    Windows XPFirefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez Slynx » środa, 2 lutego 2011, 23:09

Dobra, to ostatnie pytanie. Jak się mylę to idę do książki po odpowiedź, bo wtedy to rzeczywiście mam trochę zakrzywioną wiedzę na ten temat.

Jeśli w klasie mam jakieś funkcje, jakieś zmienne, itp, które nie są statyczne, to za każdym razem gdy użyty jest konstruktor tej klasy i tworzony jest tym samym jej obiekt, każda zmienna, każda funkcja będzie unikalna, tj. przypisana temu obiektowi ? Bo tak to wcześniej widziałem. Gdy tworzony jest obiekt tej klasy, zostają mu "przydzielone" te funkcje i zmienne tej klasy. To jeśli chodzi o teorię, bo pytanie było zupełnie inne ;p

Może po prostu....

KOD cpp:     UKRYJ  
/*poczatek klasy*/
class xxx
{
Klasa1 * obiekt_x = new Klasa1();

*/ pusty konstruktor i destruktor klasy */
jakas_funkcja()
{
obiekt_x.połączenie();
}
}
 

O coś takiego mi chodziło. Czy jak stworzę obiekt klasy xxx, to czy ten obiekt, a dokładniej "jakas_funkcja" za każdym razem dostanie własny "obiekt_x" klasy "Klasa1", czy te funkcje będą pracować na tym jednym obiekcie (obiekt_x). Konkretnie o to pytałem, bo tu miałem wątpliwość. Czy coś co nie należy do konstruktora lub funkcji (metod) składowych klasy, a jest definiowane ( lub deklarowane) globalnie również będzie unikatowe przy tworzeniu obiektu klasy "xxx"

No, w końcu poprawnie opisałem swój problem ; p

Jeszcze muszę poczytać na temat tych wektorów. Szczerze to nigdy z tego nie korzystałem, jakoś nie potrzebowałem, a może rzeczywiście ułatwiłoby kilka elementów. To tak jak z wyrażeniami regularnymi. Jak nie wiesz, że istnieją to sobie poradzisz. Za pomocą funkcji, potniesz, pokroisz i przeszukasz każdego stringa, jednak okazuje się, że można to zrobić i szybciej i krócej ; )
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 7Firefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez Cyfrowy Baron » czwartek, 3 lutego 2011, 09:57

to za każdym razem gdy użyty jest konstruktor tej klasy i tworzony jest tym samym jej obiekt, każda zmienna, każda funkcja będzie unikalna, tj. przypisana temu obiektowi ?


Konstruktor jak nazwa wskazuje używany jest tylko podczas konstrukcji, czyli tworzenia obiektu, a więc tylko raz dla jednego obiektu. To w praktyce oznacza, że cokolwiek tworzysz w konstruktorze jest tworzone tylko dla tego obiektu, tylko raz. Klasa obiektu jest tylko jego projektem, nie jest obiektem. Obiekty tworzysz w oparciu o takie projekty.

Jeżeli masz klasę xxx, to nie jest ona jeszcze obiektem, a tylko projektem. Chcąc użyć tej klasy musisz stworzyć w oparciu o nią nowy obiekt, czyli:

KOD text:     UKRYJ  
xxx *obiekt_xxx = new xxx();


Klasa xxx zawiera obiekt o nazwie obiekt_x, więc klasa xxx podczas tworzenia, tworzy obiekt_x. Zakładając, że tworzysz sobie trzy obiekty w oparciu o klasę xxx, to każdy z tych obiektów będzie miał własny obiekt_x o którym pozostałe klasy nic nie wiedzą:

KOD text:     UKRYJ  
 xxx *obiekt_xxx_1 = new xxx();
 xxx *obiekt_xxx_2 = new xxx();
 xxx *obiekt_xxx_3 = new xxx();

 /* użycie obiekt_x */
 obiekt_xxx_1->obiekt_x->... coś tam;
 obiekt_xxx_2->obiekt_x->... coś tam;
 obiekt_xxx_3->obiekt_x->... coś tam
obiekt_x jest metodą klasy xxx.

Czy coś co nie należy do konstruktora lub funkcji (metod) składowych klasy, a jest definiowane ( lub deklarowane) globalnie również będzie unikatowe przy tworzeniu obiektu klasy "xxx"


globalnie oznacza poza klasą, a więc nie jest unikatowe dla tej klasy.

Możesz tworzyć metody lokalne - dostępne tylko wewnątrz funkcji w której zostały utworzone; prywatne - deklarowane w sekcji private klasy, unikatowe dla klasy, dostępne tylko w obrębie tej klasy i nie można dobrać się do nich poza tą klasą; publiczne - deklarowane w sekcji private klasy, unikatowe dla tej klasy, ale dostępne również poza tą klasą, jednak adresowane poprzez klasę. Istnieje jeszcze sekcja protected, przeznaczenie której jest podobne do sekcji private, jednak w tej sekcji deklaruje się metody, które mają być dostępne dla klas wyprowadzonych od tej klasy. Metody globalne tworzone są poza klasą i w żaden sposób nie są związane z żadną klasą, jednak są dostępne dla wszystkich klas.

Dokładniejszy opis znajdziesz w serwisie Cyfrowy Baron w dziale: teoria -> przekazywanie obiektów i funkcji pomiędzy formularzami; teoria -> tworzenie klas; teoria -> tworzenie modułów; teoria -> tworzenie komponentów.
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
    Windows XPFirefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez polymorphism » czwartek, 3 lutego 2011, 11:11

obiekt_x jest metodą klasy xxx.

Metodami nazywa się funkcje składowe klasy, a nie jej pola.

p.s. w przykładzie z vectorem masz błąd.

Jeśli w klasie mam jakieś funkcje, jakieś zmienne, itp, które nie są statyczne, to za każdym razem gdy użyty jest konstruktor tej klasy i tworzony jest tym samym jej obiekt, każda zmienna, każda funkcja będzie unikalna, tj. przypisana temu obiektowi ?

No tak, pisałem przecież. Jeśli chodzi o funkcje składowe, nie będą one unikalne, ponieważ nie ma takiej potrzeby. To nie są dane, tylko kod wykonywalny, który generalnie* jest zawsze taki sam dla wszystkich instancji klas tego samego typu.


___
*) pomijam przypadek metod wirtualnych, bo tu sprawa troszkę inaczej wygląda.
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
    Windows XPFirefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez Cyfrowy Baron » czwartek, 3 lutego 2011, 12:38

Metodami nazywa się funkcje składowe klasy, a nie jej pola.


Wiem. Po prostu szybko pisałem nie rozgraniczałem tego jak powinienem. Początkujących może wprowadzić to w błąd, więc powinienem bardziej się postarać.

p.s. w przykładzie z vectorem masz błąd.


Poprawiłem.
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
    Windows XPFirefox

Re: Konstruktor - problem z poprawnym użyciem :/

Nowy postprzez Slynx » czwartek, 3 lutego 2011, 15:01

To dla mnie już jest wszystko jasne. Pokazując na konkretnym przykładzie, gdzie miałem wątpliwość. to było coś takiego:

KOD cpp:     UKRYJ  
                class M
                {
private:
                        CURL *curl_handle;
public:
/*
to było kilka funkcji korzystających z tego
*/

               }
 


Potem była klasa:
KOD cpp:     UKRYJ  
        class MR
                {
private:
m * cos = m();
public:
/* i ponownie jakieś funkcje wykorzystujące funkcje klasy M poprzez obiekt "cos". I tu właśnie było to moje pytanie. Czy "cos" dostanie nowy "curl_handle".
Miałem po prostu wątpliwość "czy aby na pewno", więc pomyślałem, że lepiej się upewnić niż robić to "na oko" ; ) */

}
 
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 7Firefox


  • 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 4 gości