C++: Podział kodu programu na pliki

0

Witam. Mam problem z logicznym podziałem kodu na pliki.
Mój projekt obejmuje już ponad 1500 linijek kodu, więc nie zbyt wygodnie pisać dalej w 1 pliku.

Posiadam 3 klasy, gdzie 2 z nich są zagnieżdżone w pierwszej.
Podam poniżej przykładowy kod, którego logika jest zerowa. Chodzi o przedstawienie szkieletu kodu.

Postanowilęm dokonać podziału na 4 pliki:

  1. Definicja klasy głównej
  2. Definicja klasy, która jest zagnieżdżona w klasie 1 wraz z definicjami jej metod
  3. Definicja drugiej klasy, która jest zagnieżdżona w klasie 1 wraz z definicjami jej metod
  4. Plik z metodą main głównego programu

Czy taki podział ma rację bytu, jeśli tak, jak zaplanować includy, aby program działał.

Ew alternatywnym podziałem mogłoby być:

  1. Plik z metodą main głównego programu
  2. Definicja wszystkich klas
  3. Definicje metod klas zadeklarowanych w poprzednik pliku.

Prośba o podpowiedzi :)

Kod:
Metoda main:

#include <cstdlib>
#include <iostream>


int main(int argc, char *argv[])
{

    system("PAUSE");
    return EXIT_SUCCESS;
}

Klasy porgramu:

class c1
{
    private:
            class c2;
            class c3;
            
    public:
           int napis1;
           int zmienna;
           void GetZmienna();      
};

class c1::c2
{
    private:
            int ola;
            
    public:
           int napis1;
           void GetZmienna2();      
};

class c1::c3
{
    private:
            int liczba;
            
    public:
           int napis1;
           void GetLiczba();     
};

Definicja metod:

void c1::GetZmienna()
{
     cout<<"in class 1, get zmienna\n";     
}
void c1::c2::GetZmienna2()
{
     cout<<"in class 2, get zmienn2a\n";   
}

void c1::c3::GetLiczba()
{
     cout<<"in class 3, get liczba\n";  
}
0

Ja zawsze robię tak że w headerach robię same definicje klas (tylko deklaracje jej metod), zas w osobnych je implementuję (definicje każdej metody). W każdym headerze rozpoczynam od

#ifndef NAZWAKLASY_H
#define NAZWAKLASY_H

a kończę

#endif

a jeśli potrzebujesz by korzystać w jednej klasie z drugiej to dodajesz

#include "drugawlasnaklasa.h"

i jakoś działa :) współczuję dzielenia 1500 linijek :D najlepiej robić to od początku, im mniej kodu w jednym pliku - tym łatwiej namierzyć potencjalne błędy

0
Szymek Cichy napisał(a)

Ja zawsze robię tak że w headerach robię same definicje klas (tylko deklaracje jej metod), zas w osobnych je implementuję (definicje każdej metody). W każdym headerze rozpoczynam od

#ifndef NAZWAKLASY_H
#define NAZWAKLASY_H

a kończę

#endif

a jeśli potrzebujesz by korzystać w jednej klasie z drugiej to dodajesz

#include "drugawlasnaklasa.h"

i jakoś działa :) współczuję dzielenia 1500 linijek :D najlepiej robić to od początku

No i to chyba jest najrozsądniejsze i przyzwyczai do tego jak robi to np. visual studio :)
NazwaKlasy.h - deklaracje
NazwaKlasy.cpp - definicje
i trzeba pamiętać, żeby w NazwaKlasy.cpp wrzucić #include "NazwaKlasy.h

0

dzięki :)
też sobie współczuję, bo zaraz będę musiał to dzielić ;p
ale przynajmniej nie będę szukał jednej metody 20 sekund ;p

0

Jaka jest funkcja dodawania do headerów:

#ifndef NAZWAKLASY_H
#define NAZWAKLASY_H

#endif

W swoim przykładzie nie dodałem, i działa :)

plik1

#include <cstdlib>
#include <iostream>
#include "class1.h"
#include "class2.h"
#include "class3.h"
#include "c1_methods.h"
#include "c2_methods.h"
#include "c3_methods.h"


int main(int argc, char *argv[])
{

    system("PAUSE");
    return EXIT_SUCCESS;
}

plik2: "class1.h"

class c1
{
    private:
            class c2;
            class c3;
            
    public:
           int napis1;
           int zmienna;
           void GetZmienna();      
};

plik3: "class2.h"

class c1::c2
{
    private:
            int ola;
            
    public:
           int napis1;
           void GetZmienna2();      
};

plik4: "class4.h"

class c1::c3
{
    private:
            int liczba;
            
    public:
           int napis1;
           void GetLiczba();     
};

plik5: "c1_methods.h"

void c1::GetZmienna()
{
     napis1=3;    
}

plik6: "c2_methods.h"

using namespace std;


void c1::c2::GetZmienna2()
{
     cout<<"in class 2, get zmienn2a\n";   
}

plik7: "c3_methods.h"

void c1::c3::GetLiczba()
{
     liczba =4;
}
0
cppstarter napisał(a)

Jaka jest funkcja dodawania do headerów:

#ifndef NAZWAKLASY_H
#define NAZWAKLASY_H
//tu powinno byc wszystko co chcesz miec w headerze

#endif

W swoim przykładzie nie dodałem, i działa :)

rozumiem że chodzi ci o to po co to dodawać skoro działa i bez tego ? jesli tak to odpowiadam - po to aby sie nie wykrzaczyło jak będziesz includował te same własne pliki do różnych headerów. W przeciwnym razie on tak jakby chce kilkakrotnie kompilować to samo i w końcu protestuje. Takie coś zabezpiecza cię przed tym - ifndef = jesli nie zdefiniowano to kompiluj az napotkasz #endif, zas #define tworzy stala uzywana tylko po to by sprawdzic czy juz przetrawial ten kod wczesniej czy nie. Standardowe biblioteki maja to wbudowane wiec do danie 10 razy #include <iostream> nie wykrzacza sie ale dodaj sobie do swoich klas inne swoje klasy a szybko zrozumiesz ze lepiej wyrobic sobie nawyk stosowania tego bloku

inna sprawa
jak masz headery z klasami to powiedzmy ze ok (choć nie wiem czemu masz atrybuty publiczne - przewaznie staram sie by wszystkie byly private od biedy protected, ale twoja wola), choc zapytam po co ci geter ktory jest typu void ? proponuje zmienic nazwe bo get sugeruje ze zwracasz dany atrybut

jak robisz implementacje tych klas to nie robisz tego jako class.h tylko jako class.cpp i w tym robisz #include "class.h" a potem reszte - implementacje powinny miec te same nazwy co headery tylko roznic sie rozszerzeniem - oraz w .h nie znajdzie ci bledow a w .cpp tak, wiec to kolejny argument za wprowadzeniem drobnych poprawek :)

pozniej w mainie wystarczy dodawac tylko headery bez ich implementacji

0
Szymek Cichy napisał(a)
cppstarter napisał(a)

Jaka jest funkcja dodawania do headerów:

#ifndef NAZWAKLASY_H
#define NAZWAKLASY_H
//tu powinno byc wszystko co chcesz miec w headerze

#endif

W swoim przykładzie nie dodałem, i działa :)

rozumiem że chodzi ci o to po co to dodawać skoro działa i bez tego ? jesli tak to odpowiadam - po to aby sie nie wykrzaczyło jak będziesz includował te same własne pliki do różnych headerów. W przeciwnym razie on tak jakby chce kilkakrotnie kompilować to samo i w końcu protestuje. Takie coś zabezpiecza cię przed tym - ifndef = jesli nie zdefiniowano to kompiluj az napotkasz #endif, zas #define tworzy stala uzywana tylko po to by sprawdzic czy juz przetrawial ten kod wczesniej czy nie. Standardowe biblioteki maja to wbudowane wiec do danie 10 razy #include <iostream> nie wykrzacza sie ale dodaj sobie do swoich klas inne swoje klasy a szybko zrozumiesz ze lepiej wyrobic sobie nawyk stosowania tego bloku

inna sprawa
jak masz headery z klasami to powiedzmy ze ok (choć nie wiem czemu masz atrybuty publiczne - przewaznie staram sie by wszystkie byly private od biedy protected, ale twoja wola), choc zapytam po co ci geter ktory jest typu void ? proponuje zmienic nazwe bo get sugeruje ze zwracasz dany atrybut

jak robisz implementacje tych klas to nie robisz tego jako class.h tylko jako class.cpp i w tym robisz #include "class.h" a potem reszte - implementacje powinny miec te same nazwy co headery tylko roznic sie rozszerzeniem - oraz w .h nie znajdzie ci bledow a w .cpp tak, wiec to kolejny argument za wprowadzeniem drobnych poprawek :)

pozniej w mainie wystarczy dodawac tylko headery bez ich implementacji

Aha, czyli to kwestia kompilacji :D
Co do moich klas, wiem, że są totalnie od czapy, pisałem byle co aby były 3 klasy, gdzie 2 zagnieżdżone i nie patrzylem na typu zwracane i modyfikatory dostępu :)

Już przerobiłem swój docelowy program. Działa :)
Uzupełnię teraz defy i będzie spoko.
Mimo wszystko i tak się nie przekonam do C++ ;p

W każdym razie, dzięki za poświęcony czas kolego :)

0

przyzwyczaj sie do takiego szablonu: http://4programmers.net/Forum/642607#id642607
gdyz dopoki nie "poczujesz' jak dzialaja pliki naglowkowe i straznicy #ifndef/#define/#endif, to mozesz miec duze problemy przy bardziej skomplikowanych powiazaniach miedzy klasami. Ten szablon te problemy odsunie na spory kawalek czasu

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