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

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


Abstracts.proj

Суп.ч

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 с и без ключевого слова abstract в Суп-класс

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
8 423
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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).

Спасибо! это сработало, когда я закомментировал имена аргументов, используя вашу технику, но теперь, когда я пытаюсь вытащить реализацию из заголовка, я получаю ту же ошибку связывания. Я собираюсь проголосовать за вас и изменить вопрос.

Brian 10.12.2008 21:30

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

общедоступный ссылочный класс TomatoSoup: общественный Abstracts :: Soup

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

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

Может быть достаточно хорошо ==> groups.google.com/group/microsoft.public.dotnet.languages.vc‌ /…

demoncodemonkey 10.03.2009 18:17

О боже, я искал повсюду какое-либо официальное подтверждение этого, я хотел бы проголосовать за комментарии.

Brian 12.03.2009 19:37

Другие вопросы по теме