正确包含标题

时间:2013-02-19 14:54:55

标签: c++ eclipse optimization arduino

第一个问题。如果我将类的头包含在第二个类的头文件中,我是否必须将第一个类的头包含在第二个类的.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 ++问题

它不理解对象的声明。

1 个答案:

答案 0 :(得分:0)

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

假设您的文件是本地文件,并且您的计算机的内存不是很低,那么它只会产生微不足道的差异。最近有一个关于类似主题的问题,我测量了包含一些标题或不标题之间的区别,编译了30个左右的文件(实际上是SAME文件)。并且我的机器上的“好”和“坏”运行之间的误差幅度比包括标题和不包括标题之间的差异要大得多。

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