Dynamiczne tablice obiektów bez konstruktora domyślnego

0

Mam pewien problem, otóż zastanawiam się czy można zainicjować dynamiczną tablicę obiektów wykorzystując konstruktor inny niż domyślny. Najlepiej wyjaśni to przykładowy kod.

class a{
	int la;

	public:
	a(int arg=10);
};

a::a(int arg){
	la=arg;
}

void main(){
	int ile=0;
	cin>>ile;

	a* test_a = new a[ile];
	return 0;
}

Konstruktor jest tutaj klasycznym konstruktorem domyślnym, tyle ze z parametrem. Jeżeli stworzę dynamicznie tablicę obiektów jak wyżej, konstruktor zostanie wywołany z domyślną wartością parametru i w efekcie dostanę tablicę obiektów w których pole "la" przyjmie wartość 10. Teraz załóżmy że chciałbym móc jeszcze precyzować wartość pola.

	int wartosc=0;
	cin>>wartosc;

w związku z czym, czy istnieje elegantszy sposób na wykonanie tego:

	a* test_a = new a[ile];
	for(int i=0;i<ile;i++){
		test_a[i]=a(wartosc);
	}

gdyż w przypadku gdyby mój konstruktor nie był konstruktorem domyślnym a wyglądał np. tak:

class a{
	int la;

	public:
	a(int arg);
};

to z definicji dynamicznej tablicy w ogóle byłyby nici...
...a może jest sposób na definicję takiej tablicy z obiektów nie posiadających domyślnego konstruktora? No nie wiem, coś w stylu:

	a* test_a = new a(wartosc)[ile];

wiem że to moja szalona, radosna twórczość, ale myślę że dobrze obrazuje ideę nad którą rozmyślam

0

Zrób to tak, jak robi to STL:

std::allocator<a> al;
a* array = al.allocate(10);
for(size_t i = 0; i < 10; i++
  al.construct(array[i], a(74));
//...
//zwalnianie:
for(size_t i = 0; i < 10; i++)
  al.destroy(array[i]);
al.deallocate(array, 10);

Albo użyj wektora, wyjdzie na to samo.

0

Tragedia... ale zacznijmy od początku:
1.

void main()
//...
return 0;

Co to niby znaczy? Jeśli funkcja jest typu void (jest procedurą) to nie powinna nic zwracać (ew zwracać typ void)! Poza tym main() powinien być typu int, a pisanie go z typem void to archaizm.

 test_a[i]=a(wartosc);

Gdzie a() jest konstruktorem to jest chyba jakiś zart. Obiekty zostaną stworzone za pomocą konstruktora juz w czasie alokacji pamięci, a to co napisałeś to wyciek pamięci bo tworzysz nowy zestaw obiektów... Dowód?

#include <iostream>
using namespace std;

class Test
{
  private:
    int skladnik1;
    int skladnik2;
  public:
    Test(int s=0):skladnik1(s)
    {
      if(!s) //wyzeruje nam drugi skladnik tylko jeśli argumentem jest 0
        skladnik2=0;
    }
    void wypisz()
    {
      cout<<skladnik1<<" "<<skladnik2<<endl;
    }
};

int main()
{
  Test* tablica = new Test[10];
  for(int i=0;i<10;i++)
  {
    tablica[i].wypisz(); //argumenty były domyślne więc obiekt dostanie wartości 0 i 0
    tablica[i]=Test(5); //tutaj tworzony jest NOWY obiekt, wskaźnik do starego jest tracony!
    tablica[i].wypisz(); //wypisanie składników potwierdza ze mamy nowy obiekt
  }
  return EXIT_SUCCESS;
}
0

autor:
niestety, w obecnym C++ nie ma takiej mozliwosci, i elementy kazdej tablicy, nie tylko dynamicznej, sa tworzone przez konstruktory domyslne. [jedyny wyjatek: typy POD i statyczna inicjalizacja tablicy wartosciami wprost np. cos tab[2] = { {1,1}, {2,2}}; -- w tym przypadku po prostu nie ma konstruktorow, zadnych]

w kontekscie dodawania konstruowanych elementow do konenerow zgodnych z stl, moze Cie zainteresowac http://www.boost.org/doc/libs/1_40_0/libs/utility/in_place_factories.html i pochodne, niestety ich uzycie moze byc czasem nietrywialne :)

a do przedmowcy:

Shalom napisał(a)

tablica[i]=Test(5); //tutaj tworzony jest NOWY obiekt, wskaźnik do starego jest tracony!

gdzie widziales tablice wskaznikow w poscie autora? a() nie jest bledem, nie tworzy (edit: tzn. nie alokuje na stercie) nowego obiektu, Test(5) zreszta rowniez

0
Shalom napisał(a)
void main()
//...
return 0;

Co to niby znaczy? Jeśli funkcja jest typu void...

my bad, sry za przeoczenie, nie tykałem C od 3 lat i ekspresowo staram go sobie przypomnieć [green]

@quetzalcoatl
dzięki za wyjaśnienie, podejrzewałem że tak właśnie jest, ale chciałem się upewnić.

1 użytkowników online, w tym zalogowanych: 0, gości: 1