Problem z szblonami

0

Cześc mam pewien problem pod VC++2005
Poniżej jest prosty kod aplkacji, który się ładnie kompiluje. Jednak problem następuje, gdy deklaracje i implementacje klasy rozdziele na dwa pliki klasa.h i klasa.cpp
Wywala wtedy błąd linkera

"public: int __thiscall klasa<int>::foo(void)" (?foo@?$klasa@H@@QAEHXZ) referenced in function _wmain

Oczywiście nie zapominam o #include "klasa.h" Taki sam błąd wywala pod g++.


template<class typ>class klasa
{
    private:
        typ a;
    public:
        typ foo();
};

//w pliku .cpp dodaje #include "klasa.h"
template<class typ>typ klasa<typ>::foo()
{
  return a;
}


//w przypadku podziału na pliki dodaje #include "klasa.h"
int _tmain(int argc, _TCHAR* argv[])
{
	klasa<int> a;
	a.foo();

	return 0;
}

0

na końcu pliku h zaincluduj plik cpp i nie kompiluj pliku cpp. Tak to z templatami jest, że muszą być kompilowane w takim momencie, żeby kompilator wiedział dla jakich typów przygotować klasę.

0

przeczytaj http://4programmers.net/Forum/viewtopic.php?id=126367
oraz te linki ktore tam zamiescilem - dowiesz sie wszystkiego co jak i dlaczego tak trzeba (jeszcze..)

0
nav napisał(a)

na końcu pliku h zaincluduj plik cpp i nie kompiluj pliku cpp. Tak to z templatami jest, że muszą być kompilowane w takim momencie, żeby kompilator wiedział dla jakich typów przygotować klasę.

Coś nie za bardzo działa. Nawet jeśli deklaracje i implementacje umieszcze w jednym pliku .h. Działa tylko wtedy gdy implementacja jest wewnątrz klasy, lub w tym samym pliku co funkcja main().
Odzielenie jest mi bardzo potrzebne, gdyż chcę przeciążyć operator +, a da się to tylko zrobic poprzez zaprzyjaźnienie z klasą, gdy deklaruje metodę operator + poza klasą a potem próbuje ją wywołac wywala mi błąd linkera.

0

Operatory można przeciążać nie tylko przez funkcje zaprzyjaźnione, a również przez zwykłe funkcje (niezaprzyjaźnione) jak również przez metody klasy. Poza tym ciało funkcji zaprzyjaźnionej nie musi być oddzielone od definicji klasy, może pozostać wewnątrz.
Np. operator Klasa + Klasa = Klasa

class Klasa
{
   Klasa operator+(const Klasa &K) { ... } //metoda z ciałem wewnątrz klasy
   friend Klasa operator+(const Klasa &K1, const Klasa &K2) { ... } //funkcja zaprzyjaźniona z ciałem wewnątrz klasy
}
//funkcja niezaprzyjaźniona
Klasa operator+(const Klasa &K1, const Klasa &K2) { ... }
//metoda poza ciałem klasy
Klasa Klasa::operator+(const Klasa &K) { ... }

Możliwości jest wiele.

0
manio napisał(a)

Odzielenie jest mi bardzo potrzebne

przy obecnych kompilatorach, masz tylko 2 mozliwosci:

  • wszystko w pliku .h [czyli jeden .h albo .h i #include .cpp na koncu]
  • normalne c++owa separacja na .h i .cpp, ale w .cpp na koncu trzeba podac liste WSZYTKICH specjalizacji jakie sa uzywane

serio, przeczytaj te linki co podalem. tam jest wszystko wyjasnione i wszystkie mozliwosci tez opisano

btw. oddzielenie praktycznie nigdy nie jest wymagane. serio. jesli wydaje Ci sie ze jest, to albo robisz cos bardzo niestandardowego jak podawanie kompilowanie roznych .cpp jako realizacja jednego .h albo cos probujesz zrobic nie dokonca wlasciwie

0

Dzięki quetzalcoatl. Wcześniej nie zobaczyłem twojego posta z linkami dlatego znowu coś popisałem. Teraz wszystko jasne. Co do tego odzielenia - czy potrzbne czy nie - głównie chodziło mi o przeciążenie operatora +. Tak jak napisał adf88 przeciążanie operatorów można zrobic na kilka sposobów. Ale w przypadku operatora +, nie mogę (lub raczej nie powinienem) deklarowac tego przeciążenia jako metodę klasy (czyli implementacja w klasie odpada), gdyż wtedy pierwszym argumentem dodawania będzie właśnie obiekt tej klasy - co jest be sensu dla +. Dlatego zostało tylko jako metoda zaprzyjaźniona, lub zwykła funkcja. No i tu miałem ten problem z linkerem.

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