2016-03-01 155 views
0

我试着创建一个Stopwatch结构,其目的是使用Windows QueryPerformanceCounter()函数来测量时间,如果它不存在或不被支持,它将回退到time.h中的clock() 。静态字段链接器错误

不幸的是链接错误正在发生如下:

Error LNK2001: unresolved external symbol "private: static struct Stopwatch::StopwatchInitializer Stopwatch::platformInfo" ([email protected]@@[email protected]@A) in Main.obj 

当我改变platformInfo非静态,应用程序的工作,但如果标注static,事实并非如此。

我的意图是让它保持静态,以便它只初始化一次,但链接器不合作。

这是为什么?这里是我的代码:

的StdAfx.h:

#pragma once 

#include "time.h" 

#ifdef _WIN32 
#include "windows.h" 
#endif 

//A stopwatch function provider that offers clock tick accuracy 
struct Stopwatch { 
    //holds the platform data required to initialize the stopwatch 
private: 
    struct StopwatchInitializer { 
    public: 
     double nanosecondsPerTick; 
     bool isHighResolution; 

     StopwatchInitializer() { 
#ifdef _WIN32 
      LARGE_INTEGER value; 
      isHighResolution = !!QueryPerformanceFrequency(&value); 
      nanosecondsPerTick = isHighResolution ? 1000000000.0/value.QuadPart : 1000000000.0/CLOCKS_PER_SEC; 
#elif 
      isHighResolution = false; 
      nanosecondsPerTick = 1000000000.0/CLOCKS_PER_SEC; 
#endif 
     } 
    }; 

    //static single instance of the StopwatchInitializer instance 
    //here is the error though 
    static const StopwatchInitializer platformInfo; 
    double startTimeStamp, elapsed; 
    bool isRunning; 

public: 
    //Initializes the stopwatch. 
    Stopwatch() { 
     elapsed = 0.0; 
     startTimeStamp = 0.0; 
     isRunning = false; 
    } 

    //Initializes the stopwatch with the specified pre-elapsed ticks. 
    Stopwatch(double preElapsedTicks) { 
     elapsed = preElapsedTicks; 
     startTimeStamp = 0.0; 
     isRunning = false; 
    } 

    //Gets the current time in platform-specific ticks. 
    double getTimeStamp() { 
#ifdef _WIN32 
     if (platformInfo.isHighResolution) { 
      LARGE_INTEGER num; 
      QueryPerformanceCounter(&num); 
      return (double) num.QuadPart; 
     } else 
      return (double) clock(); 
#elif 
     return (double) clock(); 
#endif 
    } 

    //Starts or resumes the stopwatch. 
    void start() { 
     if (isRunning) 
      return; 
     isRunning = true; 
     startTimeStamp = getTimeStamp(); 
    } 

    //Stops the stopwatch. 
    void stop() { 
     if (isRunning) { 
      isRunning = false; 
      elapsed += getTimeStamp() - startTimeStamp; 
     } 
    } 

    //Gets whether the stopwatch is running 
    int getIsRunning() { 
     return isRunning; 
    } 

    //Sets whether the stopwatch is running (boolean value). 
    void setIsRunning(bool value) { 
     if (value) 
      start(); 
     else 
      stop(); 
    } 

    //Gets the current elapsed ticks. 
    double getElapsedTicks() { 
     return isRunning ? (elapsed - startTimeStamp) + getTimeStamp() : elapsed; 
    } 

    //Gets the elapsed time in fortnights. 
    double getElapsedFortnights() { 
     return (platformInfo.nanosecondsPerTick * 0.00000000000000082671957671957672) * getElapsedTicks(); 
    } 

    //Gets the elapsed time in weeks. 
    double getElapsedWeeks() { 
     return (platformInfo.nanosecondsPerTick * 0.00000000000000165343915343915344) * getElapsedTicks(); 
    } 

    //Gets the elapsed time in days. 
    double getElapsedDays() { 
     return (platformInfo.nanosecondsPerTick * 0.00000000000001157407407407407407) * getElapsedTicks(); 
    } 

    //Gets the elapsed time in hours. 
    double getElapsedHours() { 
     return (platformInfo.nanosecondsPerTick * 0.00000000000027777777777777777777) * getElapsedTicks(); 
    } 

    //Gets the elapsed time in minutes. 
    double getElapsedMinutes() { 
     return (platformInfo.nanosecondsPerTick * 0.00000000001666666666666666666666) * getElapsedTicks(); 
    } 

    //Gets the elapsed time in seconds. 
    double getElapsedSeconds() { 
     return (platformInfo.nanosecondsPerTick * 0.000000001) * getElapsedTicks(); 
    } 

    //Gets the elapsed time in milliseconds. 
    double getElapsedMilliseconds() { 
     return (platformInfo.nanosecondsPerTick * 0.000001) * getElapsedTicks(); 
    } 

    //Gets the elapsed time in microseconds. 
    double getElapsedMicroseconds() { 
     return (platformInfo.nanosecondsPerTick * 0.001) * getElapsedTicks(); 
    } 

    //Gets the elapsed time in nanoseconds. 
    double getElapsedNanoseconds() { 
     return platformInfo.nanosecondsPerTick * getElapsedTicks(); 
    } 

    //Resets the elapsed time. 
    void reset() { 
     elapsed = 0.0; 
     isRunning = false; 
     startTimeStamp = 0.0; 
    } 

    //Resets the elapsed time to the specified platform-specific ticks. 
    void reset(double ticks) { 
     elapsed = ticks; 
     isRunning = false; 
     startTimeStamp = 0.0; 
    } 

    //Resets the stopwatch and restarts it. 
    void restart() { 
     elapsed = 0.0; 
     isRunning = true; 
     startTimeStamp = getTimeStamp(); 
    } 

    //Resets the stopwatch to specified platform-specific ticks and restarts it. 
    void restart(double ticks) { 
     elapsed = ticks; 
     isRunning = true; 
     startTimeStamp = getTimeStamp(); 
    } 

    //Converts nanoseconds to platform-specific ticks. 
    double convertToTicks(double nanoseconds) { 
     return nanoseconds/platformInfo.nanosecondsPerTick; 
    } 

    //Converts platform-specific ticks to nanoseconds. 
    double convertToNanoseconds(double ticks) { 
     return ticks * platformInfo.nanosecondsPerTick; 
    } 
}; 

Main.h:

#include "stdafx.h" 
#include "stdio.h" 

//entry point 
int main() { 
    Stopwatch stopwatch; 
    int x; 
    double value = 100002030.0; 
    stopwatch.start(); 
    for (x = 0; x < 100000000; x++) 
     value /= 2.2; 
    printf("Division: %fms, value: %f", stopwatch.getElapsedMilliseconds(), value); 
    value = 100002030.0; 
    stopwatch.restart(); 
    for (x = 0; x < 100000000; x++) 
     value *= 0.45454545454; 
    printf("\nMultiplication: %fms, value: %f", stopwatch.getElapsedMilliseconds(), value); 
    scanf_s(""); 
} 

回答

1

您声明为static成员platformInfo,但并没有确定,所以链接器抱怨它。要在类之外定义此静态成员,请在源代码的顶级位置添加以下行:

const Stopwatch::StopwatchInitializer Stopwatch::platformInfo; 
+0

谢谢!我不知道我必须重新声明私有静态常量字段。 :) –

+1

不只是私人和常量,[所有静态](http://stackoverflow.com/questions/3536372/defining-static-members-in-c) – yuyoyuppe

+0

欢呼,很高兴知道以供将来参考! –