Plik nagłówkowy i źródłowy.

0

Witam!
Podczas przerabiania książki Principles and Practise Using C++ natrafiłem na dość trudne zadanie uporządkowania i "zmuszenia" do działania kodu. Całość została podzielona na deklaracje w pliku nagłówkowym oraz definicję w źródłowym. Zacząłem analizować podstawiony kod i w celu zobaczenia błędów, skompilowałem całość, ale trochę się przeraziłem bo ilość nieprawidłowości wynosiła ponad 120. Ale podjąłem się zadania - jak i z resztą prawdopodobnie dam sobie radę, tak nie mam pojęcia co może być przyczyną tego, że zmienne w pliku źródłowym "mówią" o braku deklaracji lub o tym, że klasa "date" nie jest klasą ani przestrzenią nazw.

Cały plik nagłówkowy:

#include <iostream>

using namespace std;

//------------------------------------------------------------------------------

namespace Chrono {

//------------------------------------------------------------------------------

class Date {
public:
    enum Month {
        jan=1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec
    };

    class Invalid {  };                 // to throw as exception

    Date(int y, Month m, int d);       // check for valid date and initialize
    Date();                            // default constructor
    // the default copy operations are fine

    // non-modifying operations:
    int   day()   const { return d; }
    Month month() const { return m; }
    int   year()  const { return y; }

    // modifying operations:
    void add_day(int n);        
    void add_month(int n);
    void add_year(int n);

private:
    int   y;
    Month m;
    int   d;
};

//------------------------------------------------------------------------------

bool is_date(int y, Date::Month m, int d); // true for valid date

//------------------------------------------------------------------------------

bool leapyear(int y);                  // true if y is a leap year

//------------------------------------------------------------------------------

bool operator==(const Date& a, const Date& b);
bool operator!=(const Date& a, const Date& b);

//------------------------------------------------------------------------------

ostream& operator<<(ostream& os, const Date& d);
istream& operator>>(istream& is, Date& dd);

//------------------------------------------------------------------------------

} // Chrono

Przykładowy fragment pliku głównego. W pierwszych linijkach dopisałem komentarz, który tłumaczy problem:

#include "G:/Projects/Object_programming_part_4/Chrono.h"
#include "pch.h"

namespace Chrono {

	// member function definitions:

	//------------------------------------------------------------------------------

	Date::Date(int yy, Month mm, int dd) // i tu od razu już mam na przykład taki error C2653 Date: is not a class or namespace name	
		: y(yy), m(mm), d(dd) // tutaj natomiast, że yy, mm i dd są niezdeklarowane.
	{
		if (!is_date(yy, mm, dd)) throw Invalid(); // znowu mm, dd i yy niezdeklarowane oraz is_date: identifier not found
	}

	//Takie błędy jak wymienione wyżej ciągną się przez cały kod. Wstawiłem tutaj tylko jego fragment, żeby aż tak nie zaburzać czytelności

	const Date& default_date()
	{
		static const Date dd(2001, Date::jan, 1); // start of 21st century
		return dd;
	}

	//------------------------------------------------------------------------------

	Date::Date()
		:y(default_date().year()),
		m(default_date().month()),
		d(default_date().day())
	{
	}

	//------------------------------------------------------------------------------

	void Date::add_day(int n)
	{
		//..
	}

	//------------------------------------------------------------------------------

	void Date::add_month(int n)
	{
		// ...
	}

	//------------------------------------------------------------------------------

	void Date::add_year(int n)
	{
		if (m == feb && d == 29 && !leapyear(y + n)) { // beware of leap years!
			m = mar;        // use March 1 instead of February 29
			d = 1;
		}
		y += n;
	}

Prosiłbym o jakieś wskazówki, które wyjaśniłyby mi dlaczego zmienne nie wykrywają deklaracji w pliku nagłówkowym.

1

Czy aby na pewno plik Chrono.h jest "widziany" przez plik cpp? Chodzi mi o linijkę:
#include "G:/Projects/Object_programming_part_4/Chrono.h"
Poszukaj w błędach kompilacji odpowiedniego błędu z tym związanego.
Tak na marginesie - nie używaj pełnych ścieżek w include. Jeśli pliki są w tym samym katalogu to powinno być #include "Chrono.h"

0

Właśnie w tym problem, że raczej jest widziany :/ Gdy usunę linijkę z "#include" to błędów o braku deklaracji jest jeszcze więcej, co raczej udowadnia, że .cpp widzi .h.

0

Ok, nie zauważyłem komentarzy z błędami.
Np. linijka Date::Date(int yy, Month mm, int dd) jest problematyczna ponieważ typ Month nie jest widoczny z poziomu przestrzeni nazw Chrono. Zmień na:
Date::Date(int yy, Date::Month mm, int dd).
I analogicznie pozostałe podobne problemy.

0

Niestety to nie pomogło^
Dość łopatologicznie spróbowałem, zamiast stosować nagłówek, wkleić jego kod do pliku źródłowego i okazało się, że błędów było już tylko około 30, zatem cały problem zapewne leży w przestrzeniach nazw.

0

Rzeczy które mi rzucają się w oczy, bez wczytywania się w zamiary:

  • using namespace std; w pliku nagłówkowym!
  • namespace o nazwie Chrono, a jako że w standardzie jest std::chrono to wybrałbym inną nazwę (różnica o wielkość litery)
  • #include "G:/Projects/Object_programming_part_4/Chrono.h" ścieżka bezwzględna, musi być bezwzględnie zmieniona na relatywną. #include "Chrono.h" powinno działać. Zapewne to jest źródłem większości błędów. Masz taką śnieżkę: G:\Projects\Object_programming_part_4?
  • #include "pch.h" precompiled headers muszą być zawsze na samym początku pliku źródłowego (pierwszy #include)
0

...ach po prostu ach... Okazało się, że ponad 130 błędów rozwiązała zamiana kolejności "pch.h" z "Chrono.h". Naprawdę dziękuję ;) tego się nie spodziewałem.

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