Jak przekazać do tablicy obiektów parametr do konstruktora?

0

Witajcie,

Jak mogę stworzyć dynamiczną tablice obiektów klasy, żeby każdy konstruktor klasy dostał parametr o takiej samej wartości? Jest w ogóle taka możliwość czy dać sobie spokój i napisać osobną metodę którą muszę wykonać na każdym elemencie. Widziałem też sposób ze statyczną zmienną w klasie którą używał konstruktor (tylko czy to dobry "wzorzec"?). Zostaje tablica wskaźników na wskaźnik, ale mi chodzi o ciągły blok pamięci.

3

Teoretycznie jest taka możliwość, ale to mało znana składnia i każdy będzie się dziwił WTF.

#include <iostream>
using namespace std;

class Klasa
{
	int i;
public:
	Klasa(int ai)
		: i(ai)
	{
		cout << i << ' ';
	}
	~Klasa()
	{
		cout << '~' << i << ' ';
	}
};

int main()
{
	Klasa *tablica;
	int len = 5;

	tablica = (Klasa*) malloc(sizeof(Klasa) * len);
	for (int i = 0; i < len; i++)
		new(&tablica[i]) Klasa(42);

	// teraz zwalniamy:

	for (int i = 0; i < len; i++)
		tablica[i].~Klasa();
	free(tablica);
}

Jak widzisz zwolnienie takiej tablicy też nie jest zbyt piękne.

2

BTW - a czemu nie użyć std::vector? Ciągłość pamięci będzie zachowana, a używać tego wygodniej.

@MarekR22 brak konstruktora kopiującego faktycznie może być problematyczny. Ale Nie musisz przecież wywoływać domyślnego konstruktora:

#include <iostream>
#include <vector>


class Foo {
	private:
		int x;
	public:
		Foo(int a)
		: x(a) {}
		
		Foo() : Foo(5){}
		Foo(const Foo&) = default;
		Foo(Foo&&) = default;
	void print() const { std::cout << x << std::endl;}
};


int main(void) {
	// your code goes here
	std::vector<Foo> v;
	
	for (unsigned i = 0 ; i < 10 ; ++i) {
		v.emplace_back(Foo{(i*(9+i))});
	}
	
	for (const auto& el: v) {
		el.print();
	}
	return 0;
}
1

Pomyślałem sobie że musi się to dać zrobić bardziej na sposób C++:

#include <iostream>
#include <vector>
#include <memory>

using namespace std;
 
class Klasa
{
    int value_;
public:
    Klasa(int ai)
        : value_(ai)
    {
        cout << value_ << ' ';
    }
    ~Klasa()
    {
        cout << '~' << value_ << ' ';
    }
    int getValue() { return value_; }
};
 
 
int main()
{
    cout << "--- start ---\n";
    
    Klasa prototype(42);
    int len =  10;
    shared_ptr<vector<Klasa> > myarray(new vector<Klasa>(len, prototype));
    cout << "\n--- array ready ---\n";

    for (int i = 0; i < myarray->size(); i++)
        cout << (*myarray)[i].getValue() << endl;
        
    cout << "--- stop ---\n";
}

http://ideone.com/uY80dF

Edit: wersja bardziej dynamiczna.

Edit: przerobione na vector, przykład nie miał nic wspólnego z przetwarzaniem wektorowym wartości skalarnych (valarray) i dodatkowo dzięki temu zniknęła jedna niepotrzebna alokacja/destrukcja.

1

"Sposób C++" na siłę jest np. taki:

#include <iostream>
#include <memory>
#include <cstddef>

class X {
public:
  X(int x) : mX(x) { std::cout << "X(" << mX << ")\n"; }
  X(const X &other) : mX(other.mX) { std::cout << "copy X, mX = " << mX << '\n'; }
  ~X() { std::cout << "~X(" << mX << ")\n"; }
  
  int mX;
};

int main() {
  const std::size_t arraySize = 5u;
  std::allocator<X> allocator;
  
  X *array = allocator.allocate(arraySize);
  
  const X prototypeX(42);
  std::uninitialized_fill_n(array, arraySize, prototypeX);
  
  for (std::size_t i = 0; i < arraySize; ++i) {
    allocator.destroy(array + i);
  }
  
  allocator.deallocate(array, arraySize);
}

http://ideone.com/FbD63r

Ale jedyny sensowny sposób to std::vector.

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