【问题标题】:Function Declared But Not Defined? Yet It Is Defined功能已声明但未定义?然而它是被定义的
【发布时间】:2013-11-05 17:12:07
【问题描述】:

header.h

namespace VectorMath {
    static FVector Make(float X, float Y, float Z);
}

文件.cpp

namespace VectorMath {
    static FVector Make(float X, float Y, float Z)
    {
        FVector ret;
        ret.X = X;
        ret.Y = Y;
        ret.Z = Z;
        return ret;
    }
}

错误

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(541): error C2129: static function 'FVector VectorMath::Make(float,float,float)' 已声明但未声明定义 1> c:\programming****\vectormath.h(19) : 参见 'VectorMath::Make' 的声明

错误将我指向 xstring(标准字符串库的一部分)第 541 行,这似乎与任何内容都没有关系。

我想指出,删除“static”会给我链接器错误,告诉我“Make”是一个未解析的外部符号...

【问题讨论】:

  • 你的定义不一样。您在命名空间中声明了一个函数,并在命名空间之外定义了一个不同的函数。
  • 你是否在命名空间 VectorMath 中实现了 Make
  • 我确实将它们放在同一个命名空间中,抱歉更正问题。
  • 从声明和定义中删除static

标签: c++ visual-studio


【解决方案1】:

你必须去掉定义中的“静态”,无论如何,这个函数没有理由是静态的。所以你也可以把它放在声明中。

所以你可以这样写定义:

FVector VectorMath::Make(float X, float Y, float Z)
{

    FVector ret;
    ret.X = X;
    ret.Y = Y;
    ret.Z = Z;
    return ret;
}

还有这个:

namespace VectorMath
{
FVector Make(float X, float Y, float Z)
{
    FVector ret;
    ret.X = X;
    ret.Y = Y;
    ret.Z = Z;
    return ret;
}
}

干杯

【讨论】:

    【解决方案2】:

    您需要删除static,否则该函数将在不同的编译单元中不可见。只需使用

    namespace VectorMath {
        FVector Make(float X, float Y, float Z);
    }
    

    定义也是如此。

    如果这不能解决您的链接问题,您需要确保正确编译和链接file.cpp,但static 肯定是错误的。


    关于您发现问题的评论,即使用inline-functions 时无法将声明与定义分开:是的,这与方法的生成符号及其可见性具有相似的效果.我觉得奇怪的是,尽管您从未在问题中提到 inline,但您要求这是接受答案的先决条件。我怎么会知道您只是添加了您并不真正理解的随机关键字?这不是其他人帮助您解决问题的良好基础。您需要发布真实代码并对我们诚实。如果以后提出更多问题,请记住这一点。

    【讨论】:

    • 对,正如我所指出的,尽管每当我在另一个 .cpp 文件中引用 VectorMath::Make 时,删除静态都会给我带来未解析的符号。关于为什么的任何想法?除了命名空间中的函数,我是否必须使用静态类或其他东西?
    • @Slight 正如答案中已经写的那样:没有static,代码本身就可以了。您需要修复项目的构建方式。由于我没有使用 Visual Studio,我只能指出正确的方向:AFAIK 您需要将文件 file.cpp 添加为项目的源 - 但也许您需要询问 VS 用户...
    • 我向您保证,如果您在我的问题中创建这两个文件,请将它们添加到 MSVS 中的解决方案中,并删除 static 关键字。然后创建包含 vectormath.h 标头的第三个 .cpp 文件,然后尝试使用该命名空间中的函数之一,您将收到链接器错误。您还一直说“如何”我构建程序。这是一个非常基本的 dll 构建,这里没有什么花哨或错误的地方。我相信使用 extern 关键字实际上已经解决了我的问题,尽管我想测试一下。
    • 我只是将其标记为正确,然后发布一个单独的问题。
    • 我找到了链接器问题的解决方案。使用内联函数时,不能将声明与定义分开。如果您在答案中包含此内容,我会将其标记为正确。
    【解决方案3】:

    如果有帮助,代码可以在单个编译单元中工作

    http://codepad.org/mHyB5nEl

    namespace VectorMath {
    
    class FVector{
    public:
    
      float X;
      float Y;
      float Z;
    
    void show (){
    
     std::cout<< "\n \t" <<X << "\t "<< Y <<"\t "<<Z;
    }  
    
    };  
    
    
    static FVector Make(float X, float Y, float Z);
    }
    
    namespace VectorMath {
        static FVector Make(float X, float Y, float Z)
        {
            FVector ret;
            ret.X = (float)X;
            ret.Y = (float)Y;
            ret.Z = (float)Z;
            return ret;
        }
    }
    
    
    int main()
    {
    
    VectorMath::FVector result =  VectorMath :: Make(float(1.2) , float(2.2) ,float(4.2));
    result.show();
    
    }
    

    输出:

    1.2  2.2     4.2
    

    【讨论】:

    • 这没有帮助。代码在 single 编译单元中有或没有 static 都很好,static 错误,否则在具有多个编译单元的项目中使用时很好。看来 OP 真正的问题是他如何构建程序。
    猜你喜欢
    • 2014-10-14
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多