organizacja kodu dla C++ w VC

0

Witam,
uczę się programować w VC++ Express i mam kilka pytań:

  1. czy jak tworzę nowy projekt to czy on musi być w tym samym folderze w którym jest zapisane Visual? Czasami mam taki problem, że odpalam sobie plik np. .cpp lub .h i mam zablokowane przyciski :/ - nie wiem o co chodzi :(
  2. czy to jest normalne, że jak tworzę sobie plik dla 1 klasy i poza nią nic nie ma to wyskakuje błąd kompilacji, mimo, że wszystko jest ok? Nie pamiętam, co to za błąd (obecnie nie mam dostępu do programu). Z czym to jest związane? i czy da się to jakoś obejść, żeby było wszystko ok?
  3. jak tworzę sobie plik .h (nagłówkowy) to piszę w nim klasę bez ciał funkcji. Natomiast w innym pliku .cpp tworzę ciała tych funkcji i w nim załączam plik .h -> ale w głównym pliku .cpp dołączam tylko pliki .h więc skąd plik .h ma dostęp do .cpp? przecież w nim nie załączam pliku .cpp (z ciałami funkcji). -> czy jest jakieś ograniczenie, jeśli chodzi o to, gdzie jest zapisany plik .h i plik .cpp, który się do niego odnosi? np. plik h będzie w jednym folderze a plik .cpp będzie w innym - jest to możliwe?

to chwilowo tyle, ale pewnie doją jeszcze inne pytania wieczorkiem, jak znowu usiądę do piania programików :).
Ogólnie nie łapię się w tym Visual-u (dość rozbudowane narzędzie)...

0

1) Nie, tworząc projekt/solucję możesz wskazać gdzie ma być utworzony. Te zablokowane przyciski to pewnie dlatego, że w celu skompilowania czegokolwiek musisz mieć utworzony projekt, a samo otwarcie jakiegoś pliku cpp nie tworzy projektu.
2) Gdyby wszystko było ok to by nie było błędu kompilacji. Skoro nie wiesz jaki błąd to nikt Ci w tym momencie nie odpowie z czym to jest związane i jak to naprawić(błędów i problemów może być multum bardzo różnych)
3) nie ma żadnego ograniczenia gdzie się znajduje plik cpp/h tak długo jak cpp jest dołączony do projektu, a .h jest poprawnie dołączany do innych plików(poprawna ścieżka w include). Kompilatora nie musi to specjalnie interesować gdzie jest plik bleh.cpp, jeżeli kompiluje main.cpp, a tam jest bleh.h. Tym żeby to wszystko połączyć w całość zajmuje się już linker.

0

więc skąd plik .h ma dostęp do .cpp?
Odwrotnie. Kompilowany jest plik .cpp. Ale ponieważ jest w nim linijka #include "blabla.h" to w pierwszej fazie kompilacji (tzw. preprocessing) cała zawartość pliku .h jest jakby wklejana w tym miejscu do pliku .cpp i dalej kompilowana jest połączona całość.

Gdybyś usunął #include, to plik .h nie byłby w ogóle brany pod uwagę.

załóżmy że mamy dwa pliki:

ala.h

int makota();

ala.cpp

#include "ala.h"

int makota()
{
  return 42;
}

kompilator (preprocesor) rozwiązuje dyrektywy, i po prostu wkleja na pałę cały plik .h w miejsce include:

int makota();

int makota()
{
  return 42;
}

i tak wyglądający kod podlega kompilacji.

0
Azarien napisał(a)

więc skąd plik .h ma dostęp do .cpp?
Odwrotnie. Kompilowany jest plik .cpp. Ale ponieważ jest w nim linijka #include "blabla.h" to w pierwszej fazie kompilacji (tzw. preprocessing) cała zawartość pliku .h jest jakby wklejana w tym miejscu do pliku .cpp i dalej kompilowana jest połączona całość.

Gdybyś usunął #include, to plik .h nie byłby w ogóle brany pod uwagę.

załóżmy że mamy dwa pliki:

ala.h

int makota();

ala.cpp


#include "ala.h"

int makota()
{
return 42;
}

> kompilator (preprocesor) rozwiązuje dyrektywy, i po prostu wkleja na pałę cały plik .h w miejsce `include`:
> 
> 
```cpp
int makota();

int makota()
{
  return 42;
}

i tak wyglądający kod podlega kompilacji.

No tak, ale z tego co wiem, jak robimy plik main.cpp to do niego dołączamy tylko plik ala.h -> w którym nie ma #include ala.cpp -> stąd też pytanie skąd plik ala.h wie o pliku ala.cpp.

Natomiast jeśli chodzi o wywalany błąd to jest coś takiego:

1>1>------ Build started: Project: jakis projekt w C++, Configuration: Debug Win32 ------
1>LINK : error LNK2001: unresolved external symbol _mainCRTStartup
1>D:\C++ zabawa\first project\jakis projekt w C++\Debug\jakis projekt w C++.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

w klasie która wygląda tak:

#ifndef _klasa_h
#define _klasa_h

class klasa
{
public:
    double x;
};
#endif 

O co tu chodzi?

0

stąd też pytanie skąd plik ala.h wie o pliku ala.cpp.
Nie wie.

Natomiast jeśli chodzi o wywalany błąd to jest coś takiego:
Brakuje w programie funkcji main(), albo ustawiłeś zły typ projektu podczas tworzenia nowego projektu (konsolowy vs okienkowy).

0

Przecież Azerien wyjaśnił ci już o co chodzi z nagłówkami, w .h nic nie musi być widziane na zewnątrz, bo to jest jakby plik pomocniczy, jego się tylko dołącza i tyle, potem idzie jak ci Azerien pisał. Nie może wywalać ci w tej klasie, bo to błąd linkera. Pokaż cały kod.

0
xeo545x39 napisał(a)

Przecież Azerien wyjaśnił ci już o co chodzi z nagłówkami, w .h nic nie musi być widziane na zewnątrz, bo to jest jakby plik pomocniczy, jego się tylko dołącza i tyle, potem idzie jak ci Azerien pisał. Nie może wywalać ci w tej klasie, bo to błąd linkera. Pokaż cały kod.

Chyba źle wytłumaczyłem moje wątpliwości. Powiedzmy, że tworzę sobie program, który dzielę na kilka plików. W pliku .h definiuję sobie tylko "wstępne" klasy bez "ciał" funkcji. Mam np. takie pliki:

  1. klasa1.h //tu tworzę sobie szkielet pierwszej klasy, w tym pliku nic nie dołączam (?)
  2. klasa1.cpp //tu dołączam plik nagłówkowy klasa1.h tworzę sobie funkcje z tej pierwszej klasy
  3. klasa3.h //j.w.
  4. klasa4.cpp //j.w.
  5. main.cpp //tu dołączam tylko pliki nagłówkowe czyli #include klasa1.h i klasa2.h, które same nie mają zaincludowanegych plików klasa1.cpp i klasa2.cpp -> więc się zastanawiam skąd w pliku main.cpp jest dostęp do ciał tych funkcji (zaincludowane są jedynie pliki z definicjami tych klas/funkcji.
    Chyba, że jak się kompiluje wszystkie pliki .cpp to one się jakoś między sobą łączą i nie potrzebują żadnych #includów między sobą (tylko nagłówki .h)...

A teraz ważniejsza część bo coś mi nie wychodzi utworzenie działającego programu :( więc napiszę jak ja to robię:

  1. odpalam VC++
  2. file -> new -> project
  3. wybieram: Win32 Console Application (a w ogóle czym to się różni od Win32 Project)
  4. wpisuję nazwę projektu "first project" (zaznaczone jest "create directory for solution" (cokolwiek to oznacza)
  5. zaznaczam empty project -> i finish.
  6. utworzył mi się folder z 4 podfolderami External Dependencies, header files, Resource Files, Source Files -> rozumiem, że pliki .h mogę tworzyć jedynie w folderze header files? A co robię w pozostałych folderach? tzn. gdzie powinny być zapisane pliki z ciałami funkcji (.cpp) a gdzie główny plik main.cpp?

    anyway:
  7. first project utworzony więc tworzę nowy plik first_class.h w folderze Header Files o następującej postaci:
    
    #ifndef _first_class_
    #define _first_class_

class klasa1
{
public:
double x;
};
#endif


7. kompiluję ten plik i...

> 1>------ Build started: Project: first project, Configuration: Debug Win32 ------
> 1>LINK : error LNK2001: unresolved external symbol _mainCRTStartup
> 1>D:\C++ zabawa\first project\first project\Debug\first project.exe : fatal error LNK1120: 1 unresolved externals
> ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Co robię nie tak?!? :(
Bardzo proszę o pomoc!
0
  1. main.cpp //tu dołączam tylko pliki nagłówkowe czyli #include klasa1.h i klasa2.h, które same nie mają zaincludowanegych plików klasa1.cpp i klasa2.cpp -> więc się zastanawiam skąd w pliku main.cpp jest dostęp do ciał tych funkcji (zaincludowane są jedynie pliki z definicjami tych klas/funkcji.

Ah, w tym problem. Na etapie kompilacji poszczególnych plików, nie musi być dostępu do ciał funkcji — wystarczy do samych prototypów (klas bez ciał, jak to określiłeś).
Ciała funkcji znajdzie potem linker, gdy będzie składać wszystko do kupy w jednym exeku.

W ten sposób możesz mieć dwa pliki .cpp:

plika.cpp

void ala()
{
  // ... coś
}

plikb.cpp

void ala();

int main()
{
  ala();
}

jak widzisz plikb.cpp nie ma dostępu do ciała funkcji ala(), nie ma nawet żadnych nagłówków — ale ponieważ wie co to jest za funkcja ala, program się skompiluje a funkcja sama się odnajdzie.

Co robię nie tak?!?
Odpowiedziałem ci wyżej.

0

Brakuje Ci po prostu funkcji main, która jest entry pointem dla programu - od niej zaczyna się wykonywanie kodu.

0

dziękuję bardzo za pomoc! :)

Azarien napisał(a)

Co robię nie tak?!?
Odpowiedziałem ci wyżej.

rzeczywiście - powinienem zacząć od stworzenia pliku .cpp :)

A mogę prosić jeszcze o wyjaśnienie gdzie co w jakim miejscu/folderze mam zapisywać? Czy mogę zapisywać przed tymi folderami, które mi się utworzyły? Czy muszę pliki .h zapisywać tylko w folderze Headers Files a .cpp w Source Files?
A co się zapisuje w External Dependencies i Resource Files?
Pozdrawiam!

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