Witam! Ostatnio czytając kurs C++ K.Kuczmarskiego autor tego kursu powiedział, że klasy szablonowe konkretyzowane innym zestawem parametrów są zupełnie odmiennymi typami. Zatem na przykładzie szablonu TStaticArray oraz jej obiektów a10Intow i a20Floatow przedstawił kod tego szablonu, który za pomocą przeciążonego operatora przypisania powoduje, że przypisanie tych odmiennych typów jest możliwe:
template <typename T, unsigned N> class TStaticArray
{
T m_aTablica[N];
public:
const unsigned ROZMIAR = N;
T& operator[](unsigned uIndeks)
{
return m_aTablica[uIndeks];
}
template <typename T2, unsigned N2>
TStaticArray& operator=(const TStaticArray<T2, N2>& aTablica)
{
if (&aTablica != this)
{
if (N2 > N)
cerr << "za duza tablica" << endl;
for (unsigned i = 0; i < N2; ++i)
(*this)[i] = aTablica[i]; // (*this) – odwolanie do obiektu
}
return *this;
}
};
Wszystko ładnie działa aż do momentu, gdy pojawi się zapis:
int main()
{
TStaticArray<float,5> ob1;
TStaticArray<int,4> ob2;
ob1 = ob2;
return 0;
}
Wtedy VS pokazuje błąd (dla instrukcji "&aTablica != this"):
"!=": brak konwersji z "TStaticArray<float,5> *" na "const TStaticArray<int,4> *"
Oraz (dla: "(*this)[i] = aTablica[i];"):
dwuargumentowy "[": nie znaleziono żadnego operatora, który przyjmuje lewostronny operand typu "const TStaticArray<int,4>" (lub nie istnieje akceptowalna konwersja)
Zatem żeby rozwiązać problem zmieniłem w kodzie (zmiany są podświetlone):
template <typename T, unsigned N> class TStaticArray
{
public:
T m_aTablica[N]; // Niestety musiałem uczynić go publicznym wskaźnikiem :(
const unsigned ROZMIAR = N;
T& operator[](unsigned uIndeks)
{
return m_aTablica[uIndeks];
}
template <typename T2, unsigned N2>
TStaticArray& operator=(const TStaticArray<T2, N2>& aTablica)
{
if ((void*)&aTablica != (void*)this)
{
if (N2 > N)
cerr << "za duza tablica" << endl;
for (unsigned i = 0; i < N2; ++i)
(*this)[i] = aTablica.m_aTablica[i];
}
return *this;
}
};
Mój problem polega na tym, że zmiany, które wprowadziłem w kodzie są niezbyt ładne (np: publiczny wskaźnik). W taki razie jak powinien wyglądać przyzwoity oraz działający kod?
Z góry bardzo dziękuje za pomoc!
EDIT:
Póki co udało mi się częściowo rozwiązać problem używając zaprzyjaźniania:
// (...)
template<typename,unsigned> friend class TStaticArray;
T m_aTablica[N];
public:
// (...)
Aczkolwiek nadal muszę używać tej formy:
(*this)[i] = aTablica.m_aTablica[i];
Zamiast tej:
(*this)[i] = aTablica[i];
PS.
Proszę nie wincie mnie za to, że zadaje to pytanie, po prostu się uczę dopiero!