Template c++ și clase


(Stefan Davidoaia) #1

salut!îmi apar niște erori la un Template de clasa!care ar fii problema ?
header

template <typename Tip>
class Vector
{
private:
int m_iNr;
Tip * m_piData;
public:
Vector (int n);
~Vector();
Tip& operator[](int idx)
{
if (idx < 0 || idx >= m_iNr)
{
cout << "Index gresit" << endl;
exit(-1);
};
return m_piData[idx];
}
};

main

#include <iostream>
#include  "header.h"
using namespace std;
int main ()
{ int n=10;
Vector <double> vecDouble (n);
for (int i = 0; i<n; i++)
vecDouble[i] = 2.5 * i;
for (int i = 0; i<n; i++)
cout << i << " = " << vecDouble[i] << endl;
cout<<endl;
Vector <int> vecInt(n);
for (int i = 0; i<n; i++)
vecInt[i] = 2.5 * i;
for (int i = 0; i<n; i++)
cout << i << " = " << vecInt[i] << endl;
return 0;
}

și funcții

#include <iostream>
#include  "header.h"
using namespace std;
template <typename Tip>
Vector <Tip>:: Vector (int n)
{
m_iNr = n;
m_piData = new Tip[n];
}
template <typename Tip>
Vector <Tip>:: ~Vector ()
{
if (m_piData)
delete [] m_piData;
}

erori :


(Serghei Amelian) #2

Pare a fi o eroare de linking. Bănuiesc că ai uitat să incluzi în linking obiectul rezultat din compilarea fişierului care conţine implementarea constructorului şi destructorului clasei Vector.


De fapt, la template-uri nu cred că poţi să pui implementarea în fişier .cpp, cel puţin nu pentru metodele care nu au “type” fix (nu ştiu exact termenul). Trebuie să priveşti template-urile mai degrabă ca pe nişte macro-uri, care sunt expandate la compilare.


(Stefan Davidoaia) #3

Mulțumesc enorm!Am reușit conform indicaților ,le-am mutat în header!


(Sandu Liviu Catalin) #4

La template-uri se pune implementatia in header daca tipul nu este unul specific. Insa nu trebuie sa uiti de faptul ca functiile/metodele trebuie sa fie inline. Altfel primesti erori de linking pentru ca exista mai mult de o definitie.

Daca insisti sa le separi in fisiere diferite. Se creaza un fisier separat cu extensia .inl de la inline unde se pune definitia. Si se include la sfarsitul headerului ce contine declaratiile.


(Stefan Davidoaia) #5

As vrea sa știu cum exact ar arăta așa ceva !printr-un exemplu dacă se poate!sunt foarte curios de concept!


(Sandu Liviu Catalin) #6

De exemplu, ai headerul gen Array.hpp cu declaratia:

#pragma once

template < class T, unsigned N >
struct Array
{
    T m[N];

    T & operator[] (unsigned n);
    const T & operator[] (unsigned n) const;
};

#include "Array.inl"

Ai fisierul separat gen Array.inl cu definitia:

template < class T, unsigned N >
inline T & Array< T, N >::operator[] (unsigned n)
{
    return m[n];
}

template < class T, unsigned N >
inline const T & Array< T, N >::operator[] (unsigned n) const
{
    return m[n];
}

Si dupa cum observi Array.inl este inclus la sfarsitul headerului Array.hpp sau oriunde ai nevoie de definitie. Adica poti sa il incluzi si la mijloc daca vrei.

Si la final incluzi doar headerul Array.hpp in codul tau pentru ca headerul cand este citit de compiler vede ca incluzi un fisier si tot ce face el este sa dea copy->paste la ce contine Array.inl in locul unde este inclus. Pentru ca asta inseamna a include un fisier. A copia continutul in locul unde este inclus.

Sa zicem ca vreau sa il folosesc in main.cpp

#include "Array.hpp"

#include <cstdio>

int main()
{
    Array<int, 4> a{1,2,3,4};
    
    printf("%d\n", a[2]);
}

Exemplul dat de mine nu are nici o legatura cu ce vrei tu sa faci. Dar nu-mi trecea altceva prin cap.


(Stefan Davidoaia) #7

e foarte ok ,am înțeles din exemplu! :smiley: