Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Programowanie obiektowe, wybór konstruktora prz tworzeniu dynamicznej tablicy obiektów

Ostatnio zmodyfikowano 2013-03-09 16:10
Autor Wiadomość
Luk_Jab
Temat założony przez niniejszego użytkownika
[C++] Programowanie obiektowe, wybór konstruktora prz tworzeniu dynamicznej tablicy obiektów
» 2013-03-07 14:50:19
Witam, mam problem, a w zasadzie pytanie. Niedawno zacząłem się bawić programowaniem obiektowym, i wszystko to jest dla mnie jeszcze bardzo świeże. Jednym z zadań które miałem wykonać jest utworzenie klasy, która ma kilka konstruktorów. Zrobiłem to bez większych problemów. Natomiast dochodzę w pewnym momencie do przeszkody którą jest mi bardzo ciężko przeskoczyć i zastanawiam się czy polecenie jest w ogóle dobrze sformułowane.

Otóż mam utworzyć dynamiczną tablicę obiektów, o długości podanej przez użytkownika(załóżmy int n). Załóżmy że moja klasa, z tymi paroma konstruktorami ma nazwę class. Dynamiczną tablicę tworzę wtedy komendą
class * tablica = new class[ n ];
chyba dobrze to rozumiem, utworzyłem dynamiczną tablicę n obiektów klasy class. Natomiast następny punkt zadania całkowicie mnie przerasta - użytkownik powinien decydować który z konstruktorów dla każdego obiektu jest wywoływany...

Spędziłem sporo czasu na przeszukiwaniu netu, w tym forum stackoverflow.com i cplusplus.com, i jedyną sensowną informacją jaką znalazłem, to fakt że przy tworzeniu TABLICY obiektów nie mam możliwości wyboru konstruktora(nie mówiąc już o tym żeby to użytkownik go wybierał). Co najwyżej mogę sobie utworzyć tablicę obiektów, a następnie nadpisać obiekty przy użyciu konkretnego konstruktora(co z punkty widzenia efektywności programu jest głupie), ale nawet gdybym chciał tak to zrobić, to nie bardzo widzę sposób na to aby to user wybrał konstruktor.

Rozjaśni mi może ktoś ten aspekt?
P-77861
jsc
» 2013-03-07 17:21:05
A może zrobić tablicę na wskaźniki na taki obiekty?
P-77865
unimator
» 2013-03-07 17:24:34
C/C++
class CTemp
{
    CTemp() { }
    CTemp( int a ) { }
    CTemp( char a ) { }
    CTemp( int a, char b ) { }
};

CTemp ** TempArray = new CTemp *[ 4 ];

TempArray[ 0 ] = new CTemp;
TempArray[ 1 ] = new CTemp( 1 );
TempArray[ 2 ] = new CTemp( 'a' );
TempArray[ 3 ] = new CTemp( 1, 'a' );

Sam jestem ciekaw, czy jest jakieś lepsze rozwiązanie tego problemu :).
P-77866
Monika90
» 2013-03-07 20:50:10
Jeżeli chesz mieć tablicę wskaźników do obiektów jakiejś klasy, to możesz zrobić tak jak w poście unimatora.

Natomiast jeżeli to musi być tablica obiektów klasy T, to można tak:
1. Alokujesz n * sizeof(T) bajtów za pomocą malloc()
2. Konstruujesz każdy obiekt za pomocą placement new
Kiedy tablica nie jest już potrzebna
3. Wywołujesz jawnie destruktory wszystkich obiektów
4. Zwalniasz pamięc za pomocą free()

Tylko po co to, kiedy w bibliotece masz std::vector, który zrobi to wszystko sam.
C/C++
std::vector < T > v;
v.reserve( n ); //zarezerwuj miejsce na n obiektów (nie jest to potrzebne, ale można)
for( int i = 0; i < n; ++i )
{
    //zadecyduj jaki chesz konstruktor dla obiektu o indeksie i i wywołaj go
    if( cos tam )
         v.emplace_back(); //konstruktor domyślny
    else if( cos innego )
         v.epmlace_back( 1, 2, 3 ); //albo konstruktor przyjmujący 3 inty
    else
         v.emplace_back( "hello" ); //albo konstruktor T(const char*), itp...
   
}

Jeżeli masz wyjątkowo przestarzały kompilator, który nie implementuje emplace_back, to używasz push_back. Zamiast
v.emplace_back( 1, 2, 3 );
 będzie
v.push_back( T( 1, 2, 3 ) );
, itp.
P-77875
Luk_Jab
Temat założony przez niniejszego użytkownika
» 2013-03-09 14:06:45
Z tego co widzę to użycie metody emplace_back byłoby idealne, ale natknąłem się na przeszkodę. Przykład wzięty z internetu:

C/C++
#include <vector>
struct obj
{
    obj( int, double ) { }
};

int main()
{
    std::vector < obj > v;
    v.emplace_back( 1, 3.14 ); // obj in created in place in the vector
}

Wyskakuje mi błąd

error C2660: 'std::vector<_Ty>::emplace_back' : function does not take 2 arguments
          with
          [
              _Ty=obj
          ]

Podobny problem mam w moim programie, emplace_back przyjmuje tylko opcję z jednym argumentem(pomimo iż mam zdefiniowane 4 konstruktory, każdy z różną liczbą parametrów, żaden nie przyjmuje zaledwie jednego). Co jest nie tak?
P-77968
Elaine
» 2013-03-09 15:17:12
Jeżeli masz wyjątkowo przestarzały kompilator, który nie implementuje emplace_back, to używasz push_back. Zamiast
v.emplace_back( 1, 2, 3 );
 będzie
v.push_back( T( 1, 2, 3 ) );
, itp.
P-77972
Luk_Jab
Temat założony przez niniejszego użytkownika
» 2013-03-09 16:10:13
push_back działa! Stawiam piwo :) Nie sądziłem że VS2010 ma 'wyjątkowo przestarzały' kompilator, ale niech będzie. Ważne że działa i że rozumiem o co chodzi.
P-77978
« 1 »
  Strona 1 z 1