Неразрешенный токен в управляемом C ++ - PullRequest
3 голосов
/ 10 декабря 2008

У меня на руках загадка. Я пытаюсь изучить управляемый C ++, исходящий из C # фона и столкнулся с загадкой. Если у меня есть проект, который включает два класса, базовый класс Суп и производный класс 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 с и без абстрактного ключевого слова на Суп класс

Эта проблема сводит меня с ума, и я надеюсь помешать ей в будущем свести с ума других разработчиков.

ОБНОВЛЕНИЕ: Это работало с методом комментирования имени аргумента Грега Хьюджилла, когда TomatoSoup :: heat был реализован в заголовочном файле, но ошибка вернулась, когда я переместил реализацию в TomatoSoup.cpp. Я изменил вопрос, чтобы отразить это.

Ответы [ 3 ]

3 голосов
/ 10 декабря 2008

Получаемая ошибка (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) объявления.

2 голосов
/ 11 декабря 2008

Я думаю, что эта ошибка могла возникнуть из-за того, что я пытался собрать Abstracts.proj как статическую библиотеку. Когда я изменил его на .DLL, все работало нормально.

Я видел упоминание о том, что управляемый код не поддерживается статическими библиотеками, но ничего официального. У кого-нибудь есть хороший справочник, который утверждает это?

0 голосов
/ 10 декабря 2008

У меня нет большого опыта работы с CLI, но я думаю, что вы должны наследовать, используя public:

общедоступный класс ссылок TomatoSoup: общедоступный Тезисы :: Суп

...