静态字段链接器错误

Static Field Linker Error

本文关键字:错误 链接 字段 静态      更新时间:2023-10-16

我尝试创建一个秒表结构,其目的是使用 Windows QueryPerformanceCounter() 函数测量时间,如果它不存在或不受支持,它会回退到 time.h 中使用 clock()。

不幸的是,链接器错误发生如下:

Error LNK2001: unresolved external symbol "private: static struct Stopwatch::StopwatchInitializer Stopwatch::platformInfo" (?platformInfo@Stopwatch@@0UStopwatchInitializer@1@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;
    }
};

主:

#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("");
}

你声明了静态成员platformInfo,但没有定义它,所以链接器抱怨它。若要在类外部定义此静态成员,请在源的顶层添加以下行:

const Stopwatch::StopwatchInitializer Stopwatch::platformInfo;
相关文章: