ďťż

Ładny brzuch

Tak apropo w programach nie lepiej zamiast
#include "Punkt.h"
dać to
#include "Punkt.cpp"

Bynajmniej u mnie DevCpp się krztusił. Po tej operacji wszystko hulało :)
Użytkownik Mr X edytował ten post 03 wrzesień 2006, 15:35


Nie lepiej. Zawsze dołącza się tylko pliki nagłówkowe (.h), w których znajduje się definicja klasy. W pliku .cpp znajdują się definicje funkcji składowych. Nie znam kodu, który był w tych plikach, ale musiałeś popełnić jakiś błąd.

W takim razie jak daje:
#include "Punkt.h" #include <iostream> using namespace std; int main() { Punkt punkt; punkt.ustawX(10); punkt.ustawY(40); Punkt myPoint, myPoint2; myPoint.ustawWspolrzedne(punkt); myPoint2.ustawWspolrzedne(1000, 666); cout << "Pole punkt.x: " << punkt.pobierzX() << endl; cout << "Pole punkt.y: " << punkt.pobierzY() << endl; cout << "Pole myPoint.x: " << myPoint.pobierzX() << endl; cout << "Pole myPoint.y: " << myPoint.pobierzY() << endl; cout << "Pole myPoint2.x: " << myPoint2.pobierzX() << endl; cout << "Pole myPoint2.y: " << myPoint2.pobierzY(); }

Dostaje:

Kompilator: Default compiler Wykonywanie g++.exe... g++.exe "C:\Documents and Settings\beata\Pulpit\Cpp\program4.cpp" -o "C:\Documents and Settings\beata\Pulpit\Cpp\program4.exe" -I"D:\Dev-Cpp\lib\gcc\mingw32\3.4.2\include" -I"D:\Dev-Cpp\include\c++\3.4.2\backward" -I"D:\Dev-Cpp\include\c++\3.4.2\mingw32" -I"D:\Dev-Cpp\include\c++\3.4.2" -I"D:\Dev-Cpp\include" -L"D:\Dev-Cpp\lib" C:\Documents and Settings\beata\Pulpit\Cpp\program4.cpp: In function `int main()': C:\Documents and Settings\beata\Pulpit\Cpp\program4.cpp:8: error: no matching function for call to `Punkt::Punkt()' C:\Documents and Settings\beata\Pulpit\Cpp\/Punkt.h:2: note: candidates are: Punkt::Punkt(const Punkt&) C:\Documents and Settings\beata\Pulpit\Cpp\/Punkt.h:11: note: Punkt::Punkt(int, int) C:\Documents and Settings\beata\Pulpit\Cpp\program4.cpp:11: error: no matching function for call to `Punkt::Punkt()' C:\Documents and Settings\beata\Pulpit\Cpp\/Punkt.h:2: note: candidates are: Punkt::Punkt(const Punkt&) C:\Documents and Settings\beata\Pulpit\Cpp\/Punkt.h:11: note: Punkt::Punkt(int, int) C:\Documents and Settings\beata\Pulpit\Cpp\program4.cpp:11: error: no matching function for call to `Punkt::Punkt()' C:\Documents and Settings\beata\Pulpit\Cpp\/Punkt.h:2: note: candidates are: Punkt::Punkt(const Punkt&) C:\Documents and Settings\beata\Pulpit\Cpp\/Punkt.h:11: note: Punkt::Punkt(int, int) Wykonanie zakończone

A tak tylko kontrolnie się zapytam czy tworzysz projekt czy tylko operujesz na plikach w obrębie jednego folderu. Jeżeli tak to podaj treść wszystkich plików, a jeżeli nie to twórz projekt bo w czasie linkowania występuje bład :)



sprubój tak :

punkt.cpp :
#include <iostream> #include <conio> #include "punkt.h" using namespace std; /******************************************************************************/ int main() { Punkt punkt, myPoint, myPoint2; punkt.ustawX(10); punkt.ustawY(40); myPoint.ustawWspolrzedne(2000, 777); myPoint2.ustawWspolrzedne(1000, 666); cout << "Pole punkt.x: " << punkt.pobierzX() << endl; cout << "Pole punkt.y: " << punkt.pobierzY() << endl; cout << "Pole myPoint.x: " << myPoint.pobierzX() << endl; cout << "Pole myPoint.y: " << myPoint.pobierzY() << endl; cout << "Pole myPoint2.x: " << myPoint2.pobierzX() << endl; cout << "Pole myPoint2.y: " << myPoint2.pobierzY(); getch(); return 0; }

punkt.h
#include <iostream> using namespace std; /******************************************************************************/ class Punkt { int x, y; public: void ustawX (int wspX) { x = wspX; } void ustawY (int wspY) { y = wspY; } void ustawWspolrzedne(int wspX, int wspY) { x = wspX; y = wspY; } int pobierzX() { return x; } int pobierzY() { return y; } }; /******************************************************************************/

u mnie działa na Borland C++

A ja proponuję użyć głowy i pomyśleć.
Ja sobie zamiast #include "Punkt.h" mogę dać #include "Punkt.ojej" i też będzie dobrze.

#include powoduje wstawienie zawartości podanego pliku w miejsce wystąpienia tejże instrukcji, i tak należy traktować kompilowany plik .cpp - równie dobrze zamiast #include'ować można po prostu samemu przejść ręcznie drzewo dołączania i wklejać zawartość nagłówków. I będzie działać.

Podsumowując: nie include'uj rzeczy, które nie byłyby poprawne, jakbyś je tam wpisał ręcznie. W szczególności implementacje funkcji nie-inline i definicje zmiennych, bo obie te rzeczy muszą być unikatowe na skalę programu i jak wystąpią w więcej niż jednym pliku kompilowalnym, to się linker doczepi.

Pozdrawiam,
TeMPOraL.


Podsumowując: nie include'uj rzeczy, które nie byłyby poprawne, jakbyś je tam wpisał ręcznie. W szczególności implementacje funkcji nie-inline i definicje zmiennych, bo obie te rzeczy muszą być unikatowe na skalę programu i jak wystąpią w więcej niż jednym pliku kompilowalnym, to się linker doczepi.
I dlatego należy używać strażników nagłówka. czyli na początu pliku nagłówkowego dodawać coś w rodzaju
#ifndef NAZWA_PLIKU_H_ #define NAZWA_PLIKU_H_
a na końcu
#endif
W ten sposób wiemy, że plik będzie includowany tylko raz, niezależnie od tego w jakiej kolejności będą kompilowane pliki naszego projektu. I nic nie będzie sobie przeszkadzać, a twój linker będzie szczęśliwy :)


I dlatego należy używać strażników nagłówka. czyli na początu pliku nagłówkowego dodawać coś w rodzaju
#ifndef NAZWA_PLIKU_H_ #define NAZWA_PLIKU_H_
a na końcu
#endif
W ten sposób wiemy, że plik będzie includowany tylko raz, niezależnie od tego w jakiej kolejności będą kompilowane pliki naszego projektu. I nic nie będzie sobie przeszkadzać, a twój linker będzie szczęśliwy :)


Tak to prada, ale akurat to nie było powodem błędu.

Zamiast bawić się z #ifndef i tak dalej, lepiej na samym początku pliku nagłówkowego wpisać
#pragma once

Efekt ten sam.
Pozdrawiam :)

Na kompilatorach Microsoftu. Rozwiązanie wygodne, ale ekstremalnie nieprzenośne i dlatego nie świadczy o dobrej praktyce koderskiej :P.

A zawieranie #pragma once w #ifdef MSVC to ja już nie rozumiem; to jest robienie 3 nadmiarowych linijek kodu w stosunku do #ifndef / #endif, które w tym przypadku też muszą być (dla kompatybilności z innymi kompilatorami) :).
Dobranoc.

Tak mi się wydaje, że jeśli już piszesz jakiś program to nie używasz 10 różnych kompilatorów ;) Programista powinien starać się używać w miarę jedego kompilatora, kóry jest dla niego najwygodniejszy, a nie skakać pomiędzy DevCpp, Borlandem, VisualStudio i bóg wie jeszcze czym...
Co do kompatybilności #ifdef masz rację, ale ja używam VisualStudio i po prostu jestem przyzwyczajony do wygodniejszego #pragma once :)
Pozdrawiam

Nie do końca, ponieważ programista powinien zdawać sobie sprawę z istnienia innych systemów operacyjnych oprócz tego, który używa. Pisząc tylko pod jeden, w sposób całkowicie nieprzenośny tak na prawdę... ogranicza sobie rynek zbytu (alias target audience ;) ) :P. Nie mówiąc już o tym, że kod wtedy jest najczęściej nieładny i niezgodny ze standardami.

Punkt dla Ciebie, ale spójrz na to z innej strony - jeśłi ktoś pisze program korzystający z WinApi? Oczywiście są emulatory, ale korzystanie z nich jest bezsensowne. To wszystko zależy od tego, do czego służyć ma pisany program. Jeśli piszesz program dla Windowsa, to nie musisz go aż tak bardzo standaryzować. Natomiast jeśli pieszesz pod całą rodzinke system Linuxa, to jak najbardziej się z Tobą zgadzam. Mój punkt widzenia jest może trochę dziwny, ponieważ zajmuje się grami. Kiedyś pracowałem na OpenGLu, więc mogła być mowa o kompatybilności pomiędzy systemami, ale teraz siedze w DirectX.

Sory że piszę ale i ja się w tym pogubiłem...

Czy jeśli zainkluduję plik.h to czy linker dołączy również plik.cpp???


Sory że piszę ale i ja się w tym pogubiłem...

Czy jeśli zainkluduję plik.h to czy linker dołączy również plik.cpp???


Nie. Musisz to zrobic ręcznie.
Użytkownik KlyYmek edytował ten post 30 listopad 2006, 17:13
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • zsf.htw.pl
  •