Неразрешенный токен в управляемом C ++

У меня есть загадка на моих руках. Я пытаюсь изучить управляемый C ++, исходящий из фона C # и столкнувшийся с проблемой. Если у меня есть проект, который включает в себя два класса, базовый класс Soup и производный класс TomatoSoup, который я собираю как статическую библиотеку (.lib), я получаю неразрешенные токены для виртуальных методов в Soup . Вот код:


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 с и без абстрактного ключевого слова в классе Soup

Эта проблема сводит меня с ума, и я надеюсь помешать этому в будущем.

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

10.12.2008 17:54:59
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декларации чистого virtual ( ).

3
10.12.2008 18:10:20
Спасибо! это сработало, когда я закомментировал имена аргументов, используя вашу технику, но теперь, когда я пытаюсь извлечь реализацию из заголовка, я получаю ту же ошибку компоновки. Я собираюсь проголосовать за тебя и изменить вопрос.
Brian 10.12.2008 18:30:09

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

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

0
10.12.2008 18:15:14

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

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

2
19.12.2008 15:07:36
Может быть, достаточно хорошо ==> groups.google.com/group/microsoft.public.dotnet.languages.vc/…
demoncodemonkey 10.03.2009 15:17:06
О, чувак, я искал повсюду официальное подтверждение этого, я хотел бы проголосовать за комментарии.
Brian 12.03.2009 16:37:13