Strona 1 z 2 12 OstatniOstatni
Pokaż wyniki 1 do 10 z 12

Temat: [c++]podział programu na pliki

  1. #1

    Domyślnie [c++]podział programu na pliki

    Mam problem ponieważ potrzebuje dodać bardzo obszerna funkcje do programu. Nie chcę żeby znajdowała się w pliku z funkcja main() ponieważ robi się nieczytelnie. Jednak mimo moich starań kompilator nie puszcza tego co nabazgrałem. O to kod przedstawiający mój problem.
    Kod:
    //dziedziczenie_test.cpp
    #include <iostream>
    #include "klasa_pierwsza.h"
    
    void test();
    
    int main()
    
    {
    	klasa_pierwsza p1;
    	p1.a = 1;
    	std::cout << "p1.a: " << p1.a << std::endl;
    	test();
    	system("pause");
    	return 0;
    }
    Kod:
    //klasa_pierwsza.h
    ifndef klasa_pierwsza_h
    #define klasa_pierwsza_h
    
    #include <iostream>
    
    class klasa_pierwsza
    {
    
    public:
    	int a;
    	void wywal();
    };
    
    void wywal()
    {
    	std::cout << "wywal1" << std::endl;
    }
    #endif
    Kod:
    //klasa_dwa.h
    #ifndef klasa_dwa_h
    #define klasa_dwa_h
    
    #include <iostream>
    #include "klasa_pierwsza.h"
    
    class klasa_dwa : public klasa_pierwsza
    {
    	public:
    	int b;
    	void wywal2();
    };
    void wywal2()
    {
    	std::cout << "wywal2" << std::endl;
    }
    #endif
    Kod:
    //klasa_dwa.cpp
    #include <iostream>
    #include "klasa_dwa.h"
    
    void test()
    {
    	klasa_dwa k2;
    	k2.wywal2();
    }
    To mi pluje kompilator i ciężko mi się ustosunkować do tego co mówi. Błędu 2019 w ogóle nie rozumiem...
    Kod:
    1>klasa_dwa.obj : error LNK2005: "void __cdecl wywal(void)" (?wywal@@YAXXZ) already defined in dziedziczenie_test.obj
    1>klasa_dwa.obj : error LNK2019: unresolved external symbol "public: void __thiscall klasa_dwa::wywal2(void)" (?wywal2@klasa_dwa@@QAEXXZ) referenced in function "void __cdecl test(void)" (?test@@YAXXZ)
    1>C:\Users\kk\documents\visual studio 2010\Projects\dziedziczenie_test\Debug\dziedziczenie_test.exe : fatal error LNK1120: 1 unresolved externals

  2. #2
    Zarejestrowany
    Dec 2011
    Skąd
    Mazury
    Postów
    133

    Domyślnie

    Mogę się mylić, ale:
    Kod:
    #include <iostream>
    Chyba nie powinno się powtarzać w plikach nagłówkowych, skoro było już w pliku źródłowym.
    "Trąba powietrzna moich zepsutych myśli, zrywa ci z karku kołnierz ortopedyczny"

  3. #3

    Domyślnie

    next please

  4. #4
    Zarejestrowany
    Dec 2011
    Skąd
    Mazury
    Postów
    133

    Domyślnie

    Faktycznie dodatkowe załączniki do iostreama nie przeszkadzały, chociaż nie mam pojęcia po co zamieszczasz je w każdym pliku. Dziś miałem chwilę, aby zerknąć dokładniej i sprawdzić na kompilatorze, czy mam racje.

    Po pierwsze w pliku klasa_pierwsza.h nie było # przed ifndef.
    Po drugie nie było nigdzie includa do pliku klasa_dwa.cpp, więc kompliator mi słusznie krzyczał, że nie zdefiniowano funkcji test(). Dodałem odpowiednią linijkę do dziedziczenie_test.cpp i to już grało.
    Po trzecie zdefiniowałeś funkcje wywal2(), jako funkcje globalną a nie składnik klasy, przez co kompilator słusznie narzekał, że funkcja nie została zdefiniowana, podczas próby wywołania jej jako składnika klasy, która zawierała jedynie jego deklaracje. Powinno to wyglądać tak:

    Kod:
    void klasa_dwa::wywal2()
    {
    	std::cout << "wywal2" << std::endl;
    }
    Jednak osobiście polecam robić tak jak ja. Wszędzie tam, gdzie nie ma konieczności oddzielania deklaracji od definicji funkcji ( jeszcze się nie spotkałem z przypadkiem w którym to konieczne ), definiować ją w miejscu deklaracji.

    Kod:
    class klasa_dwa : public klasa_pierwsza
    {
    	public:
    	int b;
    	void wywal2()
    	{
    		std::cout << "wywal2" << std::endl;
    	}
    };
    To pozwala wyeliminować tego typu pomyłki.

    Po tych zabiegach na moim kompilatorze wszystko gra.
    Ostatnio edytowane przez Orb : 04-11-2014 - 21:09
    "Trąba powietrzna moich zepsutych myśli, zrywa ci z karku kołnierz ortopedyczny"

  5. #5

    Domyślnie

    Hasza nie ma ponieważ nie zaznaczyłem go widocznie druga sprawa, faktycznie nie zdefiniowałem funkcji jako składnik klasy(w tym kodzie, jest naskrobany na potrzebę przedstawienia problemu, oryginał ma poprawnie zdefiniowane ) trzecia sprawa to wklej cały kod na pastebin lub tu ponieważ po tych zmianach dalej ni w ząb nie mogę skompilować tego kodu. Czwarta sprawa to nie widzę powody czemu nie miał bym wywalać definicji metody poza klasę, w której jest ta metoda zadeklarowana.. Nie sprawiało mi to problemu dopóki nie miałem potrzeby dodać funkcji i przenieść jej do drugiego pliku .cpp.
    Dziękuję za zaangażowanie.
    Ostatnio edytowane przez ocb : 04-11-2014 - 23:45

  6. #6
    Zarejestrowany
    Dec 2011
    Skąd
    Mazury
    Postów
    133

    Domyślnie

    Cytat Napisał ocb Zobacz post
    Czwarta sprawa to nie widzę powody czemu nie miał bym wywalać definicji metody poza klasę,
    Nie ma żadnego, poza tym, który podałem w poprzednim poście. Najłatwiej unikać pomyłek uniemożliwiając ich popełnienie. A oto poprawiony kod, który u mnie pod kompilatorem g++ chodzi elegancko.

    Kod:
    //dziedziczenie_test.cpp
    #include <iostream>
    #include "klasa_pierwsza.h"
    #include "klasa_dwa.cpp"
    
    void test();
    
    int main()
    
    {
    	klasa_pierwsza p1;
    	p1.a = 1;
    	std::cout << "p1.a: " << p1.a << std::endl;
    	test();
    	return 0;
    }
    system("pause") usunąłem, bo mam linuxa a pod nim nie ma takiej funkcji. U siebie śmiało możesz to dodać. Nie powinno przeszkadzać.

    Kod:
    //klasa_pierwsza.h
    #ifndef klasa_pierwsza_h
    #define klasa_pierwsza_h
    
    #include <iostream>
    
    class klasa_pierwsza
    {
    
    public:
    	int a;
    	void wywal();
    };
    
    void wywal()
    {
    	std::cout << "wywal1" << std::endl;
    }
    #endif
    Kod:
    //klasa_dwa.h
    #ifndef klasa_dwa_h
    #define klasa_dwa_h
    
    #include <iostream>
    #include "klasa_pierwsza.h"
    
    class klasa_dwa : public klasa_pierwsza
    {
    	public:
    	int b;
    	void wywal2();
    };
    void klasa_dwa::wywal2()
    {
    	std::cout << "wywal2" << std::endl;
    }
    #endif
    Kod:
    //klasa_dwa.cpp
    #include "klasa_dwa.h"
    
    void test()
    {
    	klasa_dwa k2;
    	k2.wywal2();
    }
    "Trąba powietrzna moich zepsutych myśli, zrywa ci z karku kołnierz ortopedyczny"

  7. #7

    Domyślnie

    dalej to samo:
    1>klasa_dwa.obj : error LNK2005: "void __cdecl wywal(void)" (?wywal@@YAXXZ) already defined in dziedziczenie_test.obj
    1>klasa_dwa.obj : error LNK2005: "public: void __thiscall klasa_dwa::wywal2(void)" (?wywal2@klasa_dwa@@QAEXXZ) already defined in dziedziczenie_test.obj
    1>klasa_dwa.obj : error LNK2005: "void __cdecl test(void)" (?test@@YAXXZ) already defined in dziedziczenie_test.obj
    1>C:\Users\kk\documents\visual studio 2010\Projects\dziedziczenie_test\Debug\dziedziczen ie_test.exe : fatal error LNK1169: one or more multiply defined symbols found
    Używam visuala c++ 2010, więc chyba będzie trzeba zmienić jakieś opcje linkera.

  8. #8
    Zarejestrowany
    Dec 2011
    Skąd
    Mazury
    Postów
    133

    Domyślnie

    Mi tego typu komunikaty wyskakują, kiedy okazuje się, że powtarzają się includy ( w twoim przypadku powinny załatwiać to ifndefy, których ja staram się unikać, ale może jak mówisz linkier, albo kompilator coś z nimi pieprzy ). Spróbuj z pousuwanymi niepotrzebnymi załącznikami.

    Kod:
    //dziedziczenie_test.cpp
    #include <iostream>
    #include "klasa_pierwsza.h"
    #include "klasa_dwa.cpp"
    
    void test();
    
    int main()
    
    {
    	klasa_pierwsza p1;
    	p1.a = 1;
    	std::cout << "p1.a: " << p1.a << std::endl;
    	test();
    	return 0;
    }
    Kod:
    //klasa_pierwsza.h
    
    class klasa_pierwsza
    {
    
    public:
    	int a;
    	void wywal();
    };
    
    void wywal()
    {
    	std::cout << "wywal1" << std::endl;
    }
    Kod:
    //klasa_dwa.h
    
    class klasa_dwa : public klasa_pierwsza
    {
    	public:
    	int b;
    	void wywal2();
    };
    void klasa_dwa::wywal2()
    {
    	std::cout << "wywal2" << std::endl;
    }
    Kod:
    //klasa_dwa.cpp
    #include "klasa_dwa.h"
    
    void test()
    {
    	klasa_dwa k2;
    	k2.wywal2();
    }
    "Trąba powietrzna moich zepsutych myśli, zrywa ci z karku kołnierz ortopedyczny"

  9. #9

    Domyślnie

    ifndef jest efektem poszukiwań rozwiązania. Do tej pory nie miałem potrzeby z tego korzystać. Intelisense od razu reaguje na twój ostatni kod, kompilator podobnie:
    1>c:\users\kk\documents\visual studio 2010\projects\dziedziczenie_test\dziedziczenie_tes t\klasa_dwa.h(4): error C2504: 'klasa_pierwsza' : base class undefined
    1>c:\users\kk\documents\visual studio 2010\projects\dziedziczenie_test\dziedziczenie_tes t\klasa_dwa.h(11): error C2039: 'cout' : is not a member of 'std'
    1>c:\users\kk\documents\visual studio 2010\projects\dziedziczenie_test\dziedziczenie_tes t\klasa_dwa.h(11): error C2065: 'cout' : undeclared identifier
    1>c:\users\kk\documents\visual studio 2010\projects\dziedziczenie_test\dziedziczenie_tes t\klasa_dwa.h(11): error C2039: 'endl' : is not a member of 'std'
    1>c:\users\kk\documents\visual studio 2010\projects\dziedziczenie_test\dziedziczenie_tes t\klasa_dwa.h(11): error C2065: 'endl' : undeclared identifier
    I właśnie includ'y w plikach nagłówkowych rozwiązywały problem, przynajmniej ze standardowa biblioteką.

  10. #10
    Zarejestrowany
    Dec 2011
    Skąd
    Mazury
    Postów
    133

    Domyślnie

    'cout' : is not a member of 'std'
    Aż ciśnie się na usta "CO JEST KU*WA?" o_O

    No to ja wyczerpałem pomysły. Jedyne, co ci mogę doradzić, to spróbować z innym kompilatorem.
    Ostatnio edytowane przez Orb : 04-12-2014 - 16:57
    "Trąba powietrzna moich zepsutych myśli, zrywa ci z karku kołnierz ortopedyczny"

Strona 1 z 2 12 OstatniOstatni

Zasady Postowania

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •  
Subskrybuj