Trennung von Funktionsdeklaration und Definition bei Klassen



  • Hallo,

    meinem bisherigen Verständnis nach, sollte man in einer Headerdatei eine Klasse deklarieren und die Klassenmethoden in einer Sourcedatei definieren.

    Erstmal meine kleine Testklasse:

    //test2.h
    class test
    {
    public:
    	test(int value): somevalue(value)	{	}
    	void printme();
    private:
    	int somevalue;
    };
    

    Die dazugehörige Sourcedatei, in der die Klassenmethode definiert wird:

    //testc.cpp
    #include <iostream>
    #include "test2.h"
    
    void test::printme()
    {
    	std::cout << somevalue;
    }
    

    Und schließlich noch der Hauptcode:

    #include <iostream>
    #include "testc.cpp"
    
    int main()
    {
    	test a(4);
    	a.printme();
    	std::cin.get();
    }
    

    Komischerweise bekomme ich einen Linker-Fehler:

    1>testc.obj : error LNK2005: "public: void __thiscall test::printme(void)" (?printme@test@@QAEXXZ) already defined in main.obj
    1>C:\Users\bnz\Documents\Visual Studio 2010\Projects\test\Debug\test.exe : fatal error LNK1169: one or more multiply defined symbols found
    

    Ich verwende Microsoft Visual C++ 2010 Express (beta).

    Ich weiß, dass es hierfür ein extra Forum gibt, aber ich bin mir nicht sicher, ob ich einfach einen grundlegenden Fehler gemacht habe und den Wald vor lauter Bäumen nicht mehr sehe oder ob es tatsächlich am Compiler liegt.

    Der Fehler verschwindet übrigens, sobald ich die Methode "printme" direkt innerhalb der Klasse definiere.

    Seht ihr da einen Fehler?

    Vielen Dank und mfG,
    ScRaT





  • Außerdem inkludiert man keine Source-Dateien sonder nur Header-Dateien!

    Hier mal ein korrektes Beispiel:

    Header (Bla.h)

    #ifndef BLA_H
    #define BLA_H
    
    class Bla
    {
     private:
      int mTest;
    
     public:
      Bla(int t)
    
      void print();
    };
    
    #endif
    

    Source (Bla.cpp)

    #include "Bla.h"
    #include <iostream>
    
    Bla::Bla(int t)
    {
     mTest = t;
    }
    
    void Bla::print()
    {
     std::cout << mTest << std::endl;
    }
    

    Main (Main.cpp)

    #include "Bla.h"
    
    int main()
    {
     Bla blub(100);
     blub.print();
    
     return 0;
    }
    


  • @dfgdfgdfg

    In meinem Beispiel war ein Include Guard nicht nötig, da der Header nicht mehrmals inkludiert wurde - deshalb habe ich ihn weggelassen. Ist aber natürlich richtig, dass man es generell machen sollte.

    @hjzh

    Danke, das war das Problem.

    MfG,
    ScRaT


Anmelden zum Antworten