我在 DLL 项目 C++ 中遇到 "nonstatic member reference must be relative to specific object" 错误

I get a "nonstatic member reference must be relative to specific object" error in a DLL project C++

我正在开发一个 DLL 项目,我正在编写一个 class,在 header 中包含变量和函数,在 .cpp 文件中定义如下:

.h:

#ifndef RE_MATH_H
#define RE_MATH_H
#ifdef MATHFUNCSDLL_EXPORTS
#define RE_MATH_API __declspec(dllimport) 
#else
#define RE_MATH_API __declspec(dllexport) 
#endif
#define PI 3.14159265358979323846

namespace RE_Math
{
    class RE_MATH_API Point
    {
        public:
            double X;
            double Y;
            double Z;
            float alpha;

            Point(double x, double y, double z, float a);
            static void getPoint(double x, double y, double z, float a);
    };
}

和.cpp:

#include <re_math.h>

namespace RE_Math
{
    Point::Point(double x, double y, double z, float a)
    {
        X = x;
        Y = y;
        Z = z;
        alpha = a;
    }

    void Point::getPoint(double x, double y, double z, float a)
    {
        x = X;
        y = Y;
        z = Z;
        a = alpha;
    }
}

好的,所以在构造函数中我没有问题,但是在 getPoint() 函数中我得到了 "non-static member reference must be relative to specific object" 错误并且它不允许我使用变量。我尝试使变量成为静态变量,但这在相同的位置(在 getPoint() 中)给我带来了未解决的外部符号错误。 我应该怎么做才能解决这个问题?

it won't let me use the variables

您无法从 Point::getPoint 访问 XYZalpha,因为 getPoint 函数是静态的。静态成员函数不能访问实例数据成员,但它可以访问 static class 成员。

I tried making the variables static, but that gives me unresolved external symbol errors

您不能通过简单地添加 static 关键字来使成员静态化,您还需要定义它们(例如,double Point::X;)。

What should I do to fix this?

使 getPoint 函数成为非静态函数并将其更新为使用引用。

void Point::getPoint(double& x, double& y, double& z, float& a)
{
    x = X;
    y = Y;
    z = Z;
    a = alpha;
}

如果您不对参数使用引用,则函数完成后更改将丢失,因为参数是按值传递的(即,它们是原始参数的副本),这会修改仅存在于内部的临时变量getPoint 函数的范围。

您的代码有两个问题 - 一个小技术问题和一个大设计问题。

较小的问题是您的 getPoint 函数是 static。因此,它不能访问属于一个实例的数据成员,因为 class 函数只允许访问属于整个 class 的数据(即 static 数据)。您可以通过使 getPoint 函数成为非静态函数来解决此问题:

void getPoint(double x, double y, double z, float a);

更大的问题是,当你在 getPoint

中进行这些赋值时
x = X;
y = Y;
z = Z;
a = alpha;

您可能希望它们对 getPoint 的来电者产生一些影响。但是,这些只是对参数的赋值,按值传递。您对这些参数所做的任何修改都是 getPoint 的局部修改,并且不会影响传递给您的函数的表达式。

您可以通过引用传递参数来解决这个问题:

void Point::getPointComponents(double& x, double& y, double& z, float& a) {
    x = X;
    y = Y;
    z = Z;
    a = alpha;
}

并像这样使用您的函数:

double x, y, z, a;
myPt.getPointComponents(x, y, z, a);

Ampersand &表示相应的参数通过引用传递。这将参数表达式限制为可写的东西(例如其他 classes 的变量或数据成员),但它允许函数修改传入的变量。