托管C ++中未解析的令牌

时间:2008-12-10 17:54:59

标签: .net .net-2.0 polymorphism managed-c++

我的手上有一个谜。我正在尝试学习来自C#背景的托管C ++,并遇到了麻烦。如果我有一个包含两个类的项目,一个基类 Soup 和一个派生类 TomatoSoup ,我将其编译为静态库(.lib),我得到了未解析的标记中的虚拟方法。这是代码:


Abstracts.proj

Soup.h

namespace Abstracts
{
    public ref class Soup abstract
    {
    public:
        virtual void heat(int Degrees);
    };
}

TomatoSoup.h

#include "Soup.h"

namespace Abstracts
{
    public ref class TomatoSoup : Abstracts::Soup
    {
    public:
        virtual void heat(int Degrees) override;
    };
}

TomatoSoup.cpp

#include "TomatoSoup.h"

void Abstracts::TomatoSoup::heat(int Degrees)
{
    System::Console::WriteLine("Soup's on.");
}

Main.proj

Main.cpp的

#include "TomatoSoup.h"

using namespace System;

int main(array<System::String ^> ^args)
{
    Abstracts::TomatoSoup^ ts = gcnew Abstracts::TomatoSoup();

    return 0;
}

我在 Main.proj 上收到此链接时错误:

1>Main.obj : error LNK2020: unresolved token (06000001) Abstracts.Soup::heat
  1. 我尝试过设置

    virtual void heat(int Degrees)=0;
    
  2. 我尝试在基类中实现热量

    virtual void heat(int Degrees){} 
    

    并得到一个未引用的正式 参数警告视为 错误。

  3. 我用和测试了1和2 没有关于抽象的关键字 汤类
  4. 这个问题让我发疯,我希望将来能阻止其他开发商疯狂。

    UPDATE:当在头文件中实现TomatoSoup :: heat时,这与Greg Hewgill的参数名称注释方法一起使用,但是当我将实现移动到TomatoSoup.cpp时,错误又回来了。我修改了这个问题以反映这一点。

3 个答案:

答案 0 :(得分:3)

您收到的错误(LNK2020)表示链接器无法在任何地方找到Abstracts.Soup::heat函数的定义。当您将函数声明为virtual void heat(int Degrees);时,链接器将期望找到在某处定义的函数体。

如果您打算不提供函数体,并且要求子类最终覆盖该函数,则应按照解决方案1中的说明进行操作:

virtual void heat(int Degrees) = 0;

这告诉编译器你不打算实现这个功能。当你这样做会发生什么?

另外,参考您的第二个解决方案:

virtual void heat(int Degrees) {}

编译器告诉您不要在函数中引用Degrees参数。在C ++中避免此警告的一种方法是不为参数指定名称:

virtual void heat(int /*Degrees*/) {}

但是,提供一个空实现与纯虚拟(= 0)声明略有不同。

答案 1 :(得分:2)

我认为可能发生了这个错误,因为我试图将Abstracts.proj构建为静态库。当我将其更改为.DLL时,一切正常。

我已经看到过提到静态库不支持托管代码,但没有官方提供。有没有人有一个很好的参考说明这个?

答案 2 :(得分:0)

我没有太多的CLI经验,但我认为你应该使用public继承:

公共参考类TomatoSoup:公共摘要::汤