正确地包括收割台

Including headers correctly

本文关键字:收割 包括 正确地      更新时间:2023-10-16

第一个问题。如果我在第二个类的头文件中包含一个类的标头,那么我是否必须在第二类的.cpp文件中包含第一个类的标题?

在第二个类的.cpp文件中,我包括它的头,其中包括第一个类的.h文件。那么,这是正确的吗?还是我必须将第一个类的头也包含到第二个类的.cpp文件中?

第二个问题。我有两节课。第一个有静态变量和函数,所以我可以在不生成对象的情况下调用它。在第一个类中,我有一个第二个类的静态对象。现在在第二类中,我想将第一类的一些函数的返回作为操作数传递给第一类的函数。我在第二个类中没有得到任何错误,但在我之前在第一个类中提到的静态对象的声明中得到了一个错误。为什么会发生这种情况?

代码:

头文件:

 /*
  * NTPlib.h
  *
  *  Created on: 13 Feb 2013
  *  Author    : Platonas
  */
#ifndef NTP_H_
#define NTP_H_
#include "Arduino.h"
#include "SPI.h"
#include "IPAddress.h"
#include "EthernetUdp.h"
#include "Ethernet.h"
#include "DayNumber.h"
class NTP {
    private:
    public:
        static EthernetUDP Udp;
        static DayNumber DN;
        static const int Gmt = 2;
        static const unsigned int localPort = 8888;
        static const int NTP_PACKET_SIZE = 48;
        static byte packetBuffer[NTP_PACKET_SIZE ];
        static unsigned long secsSince1900;
        static unsigned long UnixTime;
        static int utchour;
        static int lcthour;
        static int min;
        static int sec;
        static int year;
        static int month;
        static int date;
        static int dayOfWeek;
        static bool timeSet;
        NTP();
        static NTP getTime();
        static bool testNtpServer();
        static void startEthernetAndUdp();
        static unsigned long sendNTPpacket(IPAddress& address);
        static int getYear();
        static int getMonth();
        static int getDate();
        static int getDayOfWeek();
        static int getUTChour();
        static int getLCThour();
        static int getMin();
        static int getSec();
        static void serialPrinting();
        virtual ~NTP();
};
#endif /* NTPLIB_H_ */

    /*
      DayNumber.h - Library for calculation of day's number on 1 and 4 years loop.
      Created by Pavlidis Kyriakos, December 20, 2012.
      Released into the public domain.
    */
    #ifndef DayNumber_H_
    #define DayNumber_H_
    #include "NTP.h"
    class DayNumber {
        private:
            int _day1YearLoop[];
            int _day4YearLoop[];
        public:
            int Days1YearLoop;
            int Days4YearLoop;
        DayNumber();
        void dayNumberCalc();
        virtual ~DayNumber();
        bool checkLeapYear(int setYear);
    };
#endif

.cpp文件:

/*
  NTP.cpp - Library for NTP server.
  Created by Pavlidis Kyriakos, Feb 13, 2013.
  Released into the public domain.
*/
#include "NTP.h"
#include "DayNumber.h"
unsigned long NTP::UnixTime = 0;
unsigned long NTP::secsSince1900 = 0;
int NTP::utchour = 99;
int NTP::lcthour = 99;
int NTP::min = 99;
int NTP::sec = 99;
int NTP::year = 99;
int NTP::month = 99;
int NTP::date = 99;
int NTP::dayOfWeek = 99;
byte NTP::packetBuffer[NTP_PACKET_SIZE ];
bool NTP::timeSet = false;
DayNumber NTP::DN = DayNumber();
EthernetUDP NTP::Udp = EthernetUDP();
NTP::NTP() {
    // TODO Auto-generated constructor stub
}
NTP NTP::getTime() {
    if (testNtpServer()) {
        timeSet = true;
        // We've received a packet, read the data from it
        Udp.read((unsigned char*)packetBuffer,NTP_PACKET_SIZE);  // Read the packet into the buffer
        // The timestamp starts at byte 40 of the received packet and is four bytes,
        // or two words, long. First, extract the two words:
        unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
        unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
        // Combine the four bytes (two words) into a long integer.
        // This is NTP time (seconds since Jan 1 1900):
        secsSince1900 = highWord << 16 | lowWord;
        // Now convert NTP time into everyday time:
        // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
        const unsigned long seventyYears = 2208988800UL;
        // Subtract seventy years:
        UnixTime = secsSince1900 - seventyYears;
        sec = UnixTime % 60;
        //Calc min
        min = (UnixTime/60)%60;
        //Calc hour
        utchour = (UnixTime/3600)%24;
        lcthour = utchour + Gmt;
        //Day of the week
        dayOfWeek = (((UnixTime/86400UL) + 3) % 7) + 1; //Setting first day Sunday = 1
        //Calculating years
        unsigned long UnixTimeToDays = UnixTime/86400UL;
        //Serial.println(UnixTimeToDays);
        unsigned long calcDaysInYears = 0;
        int calcYear = 1970;
        while((calcDaysInYears += (DN.checkLeapYear(calcYear)? 366:365)) <= UnixTimeToDays) {
            calcYear++;
        }
        year = calcYear;
        //Calculating days in this year
        calcDaysInYears -= (DN.checkLeapYear(calcYear)? 366:365);
        int daysPassedInYear = UnixTimeToDays - calcDaysInYears;
        //Set DayNumber one year loop
        DN.Days1YearLoop = daysPassedInYear + 1;
        //calculating date and month
        static const uint8_t monthDays[] = {31,28,31,30,31,30,31,31,30,31,30,31};
        int calcMonth;
        int monthLength;
        for (calcMonth = 0; calcMonth<12; calcMonth++) {
            if (DN.checkLeapYear(year)) {
                monthLength = (calcMonth == 1) ? 29: 28;
            }
            else {
                monthLength = monthDays[calcMonth];
            }
            if ( daysPassedInYear > monthLength) {
                daysPassedInYear -= monthLength;
            }
            else {
                break;
            }
        }
        month = ++calcMonth;
        date = ++daysPassedInYear;
        serialPrinting();
        return NTP();
    }
    else {
        //Error me tous ntp diavazoume wra apo DS1307
        Serial.println("pame gia RTC");
        return NTP();
    }
}
unsigned long NTP::sendNTPpacket(IPAddress& address) {
  // Set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // Eight bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  // All NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket();
}
void NTP::startEthernetAndUdp() {
    //Declaration of the mac address of ethernet shield
    byte mac[] = {0x00,0xAA,0xBB,0xCC,0xDE,0x02};
    if (Ethernet.begin(mac) == 0) {
        Serial.println("Failed to configure Ethernet using DHCP");
        // No point in carrying on, so do nothing forevermore:
        //for(;;)
        //    ;
        //Prepei na diorthwthei na kanei bypass to DHCP kai na paei sto RTC an den exei internet
    }
    Udp.begin(localPort);
}
bool NTP::testNtpServer() {
    //(193,93,167,241 ); //GR time server on athens ntp.asda.gr
    //(129,215,160,240 ); //UK extntp0.inf.ed.ac.uk School of Informatics, University of Edinburgh, Scotland, UK
    //(138,195,130,71 ); //FR ntp.via.ecp.fr VIA, Ecole Centrale Paris, France
    //(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov NTP server
    //(193,93,167,239); //GR time server on athens ChronosAsdaGr
    //(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov NTP server
    //(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov NTP server
    byte serverslist[4][4] = {
            193,93,167,241,
            129,215,160,240,
            138,195,130,71,
            132,163,4,101
    };
    IPAddress ntpServers(serverslist[0]);
    sendNTPpacket(ntpServers);
    int x = 0;
    delay(1000);
    //Checking different NTP server if someone is down
    while(!Udp.parsePacket() && x <= 3) {
        //Have to check parsePacket return.
        x++;
        IPAddress ntpServers(serverslist[x]);
        sendNTPpacket(ntpServers);
        delay(1000);
    }
    switch (x) {
        case 0:
            Serial.println("1st NTPServer working");
            return true;
            break;
        case 1:
            Serial.println("2st NTPServer working");
            return true;
            break;
        case 2:
            Serial.println("3st NTPServer working");
            return true;
            break;
        case 3:
            Serial.println("4st NTPServer working");
            return true;
            break;
        default:
            Serial.println("All NTP Servers are Down");
            return false;
    }
}
int NTP::getYear() {
    do {
        getTime();
    } while(timeSet == false);
    return year;
}
int NTP::getMonth() {
    do {
        getTime();
    }while(timeSet == false);
    return month;
}
int NTP::getDate() {
    do {
        getTime();
    } while(timeSet == false);
    return date;
}
int NTP::getDayOfWeek() {
    do {
        getTime();
    } while(timeSet == false);
    return dayOfWeek;
}
int NTP::getUTChour() {
    do {
        getTime();
    } while(timeSet == false);
    return utchour;
}
int NTP::getLCThour() {
    do {
        getTime();
    } while(timeSet == false);
    return lcthour;
}
int NTP::getMin() {
    do {
        getTime();
    } while(timeSet == false);
    return min;
}
int NTP::getSec() {
    do {
        getTime();
    } while(timeSet == false);
    return sec;
}
void NTP::serialPrinting() {
    //Serial.PRINTS
    //print seconds since 1900
    Serial.print("Seconds since Jan 1 1900 = " );
    Serial.println(secsSince1900);
    // print Unix time:
    Serial.print("Unix time = ");
    Serial.println(UnixTime);
    //print year
    Serial.print("the year is :");
    Serial.println(year);
    //print month
    Serial.print("Month is : ");
    Serial.print(month);
    //print date
    Serial.print(" Date is: ");
    Serial.println(date);
    //print dayOfWeek
    Serial.print("the day is : ");
    Serial.println(dayOfWeek);
    //printnumber of days that passed in this year (this day counts DayNumber object)
    Serial.print("This day is the number:");
    Serial.println(DN.Days1YearLoop);
    //print Local Time Hour
    Serial.print("The LTC time is ");
    Serial.println(lcthour);
    // Print the hour, minute and second:
    Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
    Serial.print(utchour); // Print the hour (86400 equals secs per day)
    Serial.print(':');
    if ( min < 10 ) {
        // In the first 10 minutes of each hour, we'll want a leading '0'.
        Serial.print('0');
    }
    Serial.print(min); // Print the minute (3600 equals secs per minute)
    Serial.print(':');
    if ( sec < 10 ) {
        // In the first 10 seconds of each minute, we'll want a leading '0'.
        Serial.print('0');
    }
    Serial.println(sec); // Print the seconds
}
NTP::~NTP() {
    // TODO Auto-generated destructor stub
}

/*
  DayNumber.cpp - Library for Calculation of Day's Number on 1 and 4 years loop.
  Created by Pavlidis Kyriakos, December 20, 2012.
  Released into the public domain.
*/
#include "DayNumber.h"

DayNumber::DayNumber() {
}
void DayNumber::dayNumberCalc() {
    int setYear = NTP::getYear();
    int setMonth = NTP::getMonth();
    int setDay = NTP::getDate();
    //Days that passed from the begging of the year for the 1st Day each Month
    int _day1YearLoop[] = {0,31,59,90,120,151,181,212,243,273,304,334};
    //i = _day1YearLoop;
    //Days that passed from the beginning of the second Year since the for the 1st Day of the running Year in 4 years loop.
    int _day4YearLoop[] = {366,731,1096};
    if (checkLeapYear(setYear)) {
        if (setMonth>2) { //Diorthwsi gia ton mina flebari
            Days1YearLoop = *(_day1YearLoop+(setMonth-1)) + setDay + 1;
            Days4YearLoop = Days1YearLoop;
        }
        else {
            Days1YearLoop = *(_day1YearLoop+(setMonth-1)) + setDay;
            Days4YearLoop = Days1YearLoop;
        }
    }
    else {
        Days1YearLoop = *(_day1YearLoop + (setMonth-1)) + setDay;
        switch (setYear%4) {
            case 1:
                Days4YearLoop = *(_day4YearLoop) + Days1YearLoop;
                break;
            case 2:
                 Days4YearLoop = *(_day4YearLoop+1) + Days1YearLoop;
                 break;
            case 3:
                Days4YearLoop = *(_day4YearLoop+2) + Days1YearLoop;
                break;
            Default:;
                break;
        }
    }
}

DayNumber::~DayNumber() {
}

bool DayNumber::checkLeapYear(int setYear) {
    if (setYear%4 == 0) {
        return true;
    }
    else {
        return false;
    }
}

错误出现在NTP.h的第一个标题,上面写着

说明资源路径位置类型"DayNumber"未命名类型NTP.h/NTP/lib行24 C/C++问题

它不理解对象的声明。

最好包括当前文件所依赖的所有文件。假设您更改了"DayNumber.h",使其不再需要"NTP.h",现在您的代码将无法编译。

假设你的文件是本地的,并且你的机器内存不是很低,这只会产生很小的影响。最近有一个关于类似主题的问题,我测量了是否包含一些头,编译大约30个文件(实际上是同一个文件)之间的差异。在我的机器上,"好"answers"坏"运行之间的误差幅度比包括标题和不包括标题之间的差异大得多。

至于你的第二个问题,它实际上是由包含"NTP.h"引起的,而"DayNumber.h"中不需要"NTP.h",所以你应该"不包含它"。但是,如果您的实际情况是,您有一个类需要知道另一个类,那么您需要使用前向声明,例如class NTP;-现在,您可以使用NTP *NTP &向NTP类传递/存储指针/引用。在NTP类完全定义之前,您仍然不能使用NTP类内部的内容。