У меня на руках загадка. Я пытаюсь изучить управляемый C++, исходящий из фона C#, и столкнулся с проблемой. Если у меня есть проект, который включает два класса, базовый класс Суп и производный класс Томатный суп, который я компилирую как статическую библиотеку (.lib), я получаю неразрешенные токены для виртуальных методов в Суп. Вот код:
Суп.ч
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.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
Я пробовал установить
virtual void heat(int Degrees)=0;
Я пробовал реализовать тепло в базовом классе
virtual void heat(int Degrees){}
и получить формальный предупреждение о параметре рассматривается как ошибка.
Эта проблема сводит меня с ума, и я надеюсь, что в будущем она не сведет с ума других разработчиков.
Обновлено: Это работало с методом комментирования имени аргумента Грега Хьюгилла, когда TomatoSoup :: heat был реализован в файле заголовка, но ошибка вернулась, когда я переместил реализацию в TomatoSoup.cpp. Я изменил вопрос, чтобы отразить это.





Полученная вами ошибка (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).
У меня нет большого опыта работы с CLI, но я думаю, что вы должны наследовать, используя public:
общедоступный ссылочный класс TomatoSoup: общественный Abstracts :: Soup
Я думаю, что эта ошибка могла возникнуть из-за того, что я пытался создать Abstracts.proj как статическую библиотеку. Когда я изменил его на .DLL, все заработало.
Я видел упоминание об управляемом коде, который не поддерживается статическими библиотеками, но ничего официального. У кого-нибудь есть хорошая ссылка, в которой говорится об этом?
Может быть достаточно хорошо ==> groups.google.com/group/microsoft.public.dotnet.languages.vc /…
О боже, я искал повсюду какое-либо официальное подтверждение этого, я хотел бы проголосовать за комментарии.
Спасибо! это сработало, когда я закомментировал имена аргументов, используя вашу технику, но теперь, когда я пытаюсь вытащить реализацию из заголовка, я получаю ту же ошибку связывания. Я собираюсь проголосовать за вас и изменить вопрос.