szablon klasy vec

0

Pisze szablon klasy vec, w ktorej musze zdefiniowac:
Komplet konstruktorów (łącznie z konstruktorem przemieszczającym i konstruktorem z listą inicjacyjną)
Destruktor
Operatory podstawienia (zwykły i przemieszczający)
Operatory indeksowania (zwykły i const)
Metoda size (okreslajaca liczbe elementów w obiekcie vec)
Metoda push_back (dołożenie nowego elementu na koniec kolekcji)
Operator wyprowadzenia na strumień wyjściowy << ma być zdefiniowany jako szablon funkcji.
do tej pory stworzylem cos takiego; prosze o sprawdzenie i pomoc w pozostalych elementach zadania :)

class vec
{
	int sz;             // liczba elementów
	string* elem;       // wskazanie na pierwszy element

public:
	vec(int s = 0) 
	:sz(s > 0 ? s : 0),
	elem(new string[sz])

	{                    
		for (int i = 0; i < size(); ++i)
		elem[i] = 0.0;
	}

	vec(const vec& src)
	:sz(0),
	elem(nullptr)
	{
		*this = src;
	}

	~vec()
	{
		delete[] elem;
	}

	int size() const {return sz;} 

	void push_back(string nv)
	{
		string *pbuf = new string[size() + 1]; 
		for (int i = 0; i < size(); ++i)
		pbuf[i] = elem[i];
		pbuf[size()] = nv;
		++sz;
		delete[] elem;
		elem = pbuf;
	}

	string& operator[](int idx)
	{
		if (idx < 0 || idx >= size())
		throw string("Przekroczony zakres rozmiar vec");
		return elem[idx];
	}

	string operator[](int idx) const
	{
		if (idx < 0 || idx >= size())
		throw string("Przekroczony zakres rozmiar vec");
		return elem[idx];
	}

	int operator[](const string& s)
	{
		for (int i = 0; i < size(); i++)
		{
			if (elem[i] == s)
			return i;
		}

		push_back(s);
		return size()-1;

	}

	vec& operator=(const vec& right)
	{
		if (this == &right)
		return *this;
		delete[] elem;
		sz = right.size();
		elem = new string [size()];
		for (int i=0; i<size(); ++i)
		{
			elem[i] = right[i];
		}
		return *this;
	}
};
ostream& operator<<(ostream& os, const vec& right)
{
	os << '[';
	for (int i = 0; i < right.size(); i++)
		os << right[i] << ' ';
	return os << ']';
}
2

1.Brakuje komentarzy (przede wszystkim pełnych komentarzy do każdej metody).
2.Dlaczego nie wykorzystałeś szablonów?
3.Masz beznadziejne nazewnictwo. int sz; przecież za cholerę nie można się domyślić co to oznacza*, trzeba albo zgadywać, albo patrzeć w kod. count było za mało czytelne? Podobnie z tymi wszystkimi vec(int s = 0) (co za s?), void push_back(string nv) (dlaczego nv? dlaczego jakieś pbuf? skąd tyle magicznych, przypadkowych zbitek liter?)
4.Raz piszesz i++, a potem ++i - wykorzystuj wszędzie preinkrementację (wyrobisz sobie dobry nawyk na przyszłość, zanim @_13th_Dragon Cię ochrzani za to :P).
5.Pilnuj typów. Dlaczego gdzieniegdzie indeksy są intami? Bo jeszcze mogę zrozumieć przyjmowanie inta w operatorze [], ale kompletnie nie rozumiem, dlaczego tutaj:

for (int i = 0; i < size(); ++i)

A teraz porównaj swój kod z tym: ```cpp void push_back(string value) { string *newBuffer = new string[this->count + 1];
// można by także wykorzystać memcpy()
for (size_t i = 0; i < this->count; ++i) {
	newBuffer[i] = this->buffer[i];
}

newBuffer[this->count] = value;

delete[] this->buffer;
this->buffer = newBuffer;

++this->count;

}

I wio do poprawek ;)

Edit: zauważ, że ja do każdego pola klasy jawnie odwołuję się przez `this` - wyrobiłem u siebie taki nawyk, ponieważ wyraźniej można wskazać wtedy zmienne lokalne oraz pola, ale zgaduję, że `kto co lubi`. Inną przyjętą konwencją jest wykorzystywanie prefiksu `m`, np. `mCount`.

Edit 2: `*` teraz zauważyłem, że akurat do `sz` masz komentarz. Cóż - pisz kod tak, aby był komentarze były zbędne (poza tymi najważniejszymi do każdej funkcji/metody).
1
  1. Może przepiszę początek:
class vec
  {
   private:
   size_t count; // miałeś int, czyżby przewidywałeś ujemny rozmiar? 
   string *buffer;
   public:
   vec(size_t count=0):count(count),buffer(new string[count]) // zobacz size_t i żadnej gimnastyki z ujemnymi liczbami
     {                    
      for(size_t i=0;i<vec::count;++i) vec::buffer[i]="0.0"; // trochę to dziwne wpisywanie 0.0 do napisu, nie wiem o co ci chodziło
     }
   void swap(vec &v) // bardzo sprytna metoda, pozwala parę rzeczy zrobić znacznie prościej
     {
      std::swap(vec::count,v.count); // tu inne podejście jeżeli nie podoba ci się podejścia z this-> oraz `m` wspomniane przez Patryk27
      std::swap(vec::buffer,v.buffer);
     }
   vec(const vec &v):count(v.count),buffer(new string[count]) // pamiętać aby count był przed buffer
     {                    
      for(size_t i=0;i<vec::count;++i) vec::buffer[i]=v.buffer[i];
     }
   vec &operator=(const vec &v) // a teraz patrz na to, dzięki swap mamy
     {
      vec tmp(v);
      swap(tmp);
      return *this;
     }
  1. Używasz string a nie używasz vector, WTF? Sugestia - w tym projekcie nie powinieneś używać typu string
  2. Wg zamówienia @Patryk27 tu masz spisano czemu: http://4programmers.net/Forum/1101404

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