Podział projektu na pliki a programowanie obiektowe

Podział projektu na pliki a programowanie obiektowe
A1
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 5 lat
  • Postów:21
0

Cześć, próbuję zrobić mój pierwszy projekt używając programowania obiektowego. Dlaczego w menu.cpp mogę zdefiniować funkcję "adam" z pliku gra.cpp, a nie mogę w pliku menu.cpp stworzyć obiektu "gracz" klasy "adam" z pliku gra.cpp?

Funkcja:

Kopiuj
//main.cpp
#include "menu.hpp"

int main()
{
    menu();
    return 0;
}
Kopiuj
//menu.hpp
#ifndef MENU_HPP_INCLUDED
#define MENU_HPP_INCLUDED
#include "gra.hpp"

#include <iostream>
using namespace std;
void menu();

#endif // MENU_HPP_INCLUDED
Kopiuj
// menu.cpp

#include "menu.hpp"
void menu(){
    adam(5);
}
Kopiuj
//gra.hpp
#ifndef GRA_HPP_INCLUDED
#define GRA_HPP_INCLUDED

#include <iostream>
using namespace std;
void adam(short pkt);

#endif // GRA_HPP_INCLUDED
Kopiuj
//gra.cpp
#include "gra.hpp"
void adam(short pkt){
    cout << "Adam ma " << pkt << " pkt";
}

Klasa:

Kopiuj
//main.cpp
#include "menu.hpp"

int main()
{
    menu();
    return 0;
}
Kopiuj
//menu.hpp
#ifndef MENU_HPP_INCLUDED
#define MENU_HPP_INCLUDED
#include "gra.hpp"

#include <iostream>
using namespace std;
void menu();

#endif // MENU_HPP_INCLUDED
Kopiuj
// menu.cpp

#include "menu.hpp"
void menu(){
    adam gracz(5);
    cout << "Adam ma " << gracz.ilepkt();
}
Kopiuj
//gra.hpp
#ifndef GRA_HPP_INCLUDED
#define GRA_HPP_INCLUDED

#include <iostream>
using namespace std;
class adam;

#endif // GRA_HPP_INCLUDED
Kopiuj
//gra.cpp
#include "gra.hpp"

class adam{
private:
    short pkt;
public:
    adam(short p){
    pkt = p;
    }

    short ilepkt(){
        return pkt;
    }
};

Zwracany błąd:

E:\Moje Dokumenty\Programowanie\c++\gra\menu.cpp|5|error: variable 'adam gracz' has initializer but incomplete type|

edytowany 4x, ostatnio: adamowski10
mwl4
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Wrocław
  • Postów:402
0

Przedstawię ci inny model podziału na pliki. Jest o niebo lepszy, wszystko się ładnie łączy, standardowe nagłówki są użyte tylko raz i koniec.

Ok. Załóżmy że mamy plik main.cpp.
Następnie tworzymy plik Includes.h/hpp, oraz tworzymy plik nagłówkowy i plik źródłowy dla klasy.
Niech to będzie klasa CSamochod.

I teraz robimy tak: W includes.h zawieramy biblioteki standardowe oraz plik nagłówkowy klasy.
W kodzie źródłowym klasy zawieramy plik includes.h, w mainie zawieramy includes.h, a w pliku nagłówkowym klasy nie zawieramy niczego. Kompilator sam poskłada pliki tak, że w Includes znajdą się wszystkie definicje klas + na początku będą domyślne nagłówki, przez co daje to swobodny dostęp.

No i przykład:
Main.cpp:

Kopiuj
#include "Includes.h"

int main(int, char**)
{
	CSamochod * pSamochod = new CSamochod();
	pSamochod->Method();
	delete pSamochod;
	
	return 0;
}
 

Includes.h:

Kopiuj
#pragma once // dla zawarcia pliku tylko raz! można użyć ifndef..itd.
#include <cstdio>
#include <Windows.h>
#include <cstdlib>
#include <cmath>
// inne

#include "Samochod.h"
 

Samochod.h:

Kopiuj
#pragma once
class CSamochod
{
public:
	CSamochod();
	~CSamochod();

	void Method();
};

Samochod.cpp:

Kopiuj
 
#include "Includes.h"

CSamochod::CSamochod()
{
}

CSamochod::~CSamochod()
{
}

void CSamochod::Method()
{
	printf("CSamochod::Method()");
}

W ten sposób, możesz dołączać kolejno następne pliki nagłówkowe z klasami do includes.h, dodawać nowe kody źródłowe do projektu includujące includes.h, w których są metody.
Sam używam takiego czegoś, i jestem w sumie zadowolony.


Asm/C/C++
edytowany 3x, ostatnio: mwl4
n0name_l
#pragma once afair nie jest [niestety] w standardzie.
mwl4
Napisałem, że można użyć #ifndef, #define. A to, że nie jest w standardzie no to cóż.. czysty idiotyzm. Jedynie panowie z msu pomyśleli że coś takiego jest przydatne.
A1
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 5 lat
  • Postów:21
0
gośćabc napisał(a):

ten pomysł z includes nie jest zbyt dobry,

w plikach cpp powinniśmy includować tylko to co nam potrzebne

a w nagłówkach wprowadzać forward deklarację, gdzie tylko się da

Mówisz o pomyśle mwl4? W takim razie jak rozwiązać mój problem?

edytowany 1x, ostatnio: adamowski10
EM
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 11 lat
  • Postów:271
0

@mwl4 Dla mnie też nie wydaje się to do końca najlepsze rozwiązanie - chciałbym mieć w danych plikach dołączane tylko to co w tych plikach wykorzystuje i to powinno być według mnie jasno zaznaczone.

W sumie można by zapytać czy wszystkie niezbędne rzeczy można by zaincludować w pliku .h? Teoretycznie tak a praktycznie są przeciwwskazania?

edytowany 1x, ostatnio: emacs
mwl4
Druga część postu: Ja to właśnie zrobiłem dzięki includes.h, a przeciwwskazania: jeszcze takowych nie zauważyłem. Czas kompilacji jest praktycznie ten sam jakbym robił waszym sposobem, a jest przy tym dużo mniej kopaniny z includowaniem.
A1
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 5 lat
  • Postów:21
0
gośćabc napisał(a):

klasy definiujemy w plikach nagłówkowych, czyli na bank nie w gra.cpp, przenieś definicję​ do gra.h

i zaincluduj gra.h w plikach cpp, w których używasz klasy Adam czyli w menu.cpp

miej świadomość, że tworzysz tam Adama lokanie więc po wykonaniu menu() Adam zniknie

Super, dzięki działa ;) ale skoro jest to Twoje "ale", to jak polecałbyś to zrobić w inny sposób?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.