Предупреждение компоновщика MSVC++ при использовании идиомы PIMPL в C++/CLI

Я пишу сборку .NET, используя C++/CLI (версия 9.0), и я хотел бы использовать идиому PIMPL, чтобы не помещать ненужные вещи в мой общедоступный заголовок. К сожалению, когда я пытаюсь перенаправить объявление класса, а затем использую для него дескриптор отслеживания, я получаю предупреждение компоновщика 4248:

предупреждение LNK4248: неразрешенный токен typeref (0100000E) для «MyNamespace.PrivateClass»; образ может не запуститься

Кажется, это так, использую ли я класс CLI или собственный класс для класса реализации.

Пример кода показан ниже:

namespace MyNamespace
{
    ref class PrivateClass; // forward dec

    ref class MyPublicClass
    {
    private:
        PrivateClass^ m_Imp;
    };
}

К сожалению, объяснение предупреждения Microsoft не слишком информативно.


person Brian Stewart    schedule 02.12.2008    source источник


Ответы (2)


Я думаю, вы используете две технологии, которые не очень хорошо сочетаются друг с другом:

Естественное применение pimpl состоит в том, чтобы избежать необходимости постоянно вносить изменения в заголовочный файл, что приводит к большим перекомпиляциям в больших проектах C++.

Естественным приложением для C++/cli является написание небольших фрагментов взаимодействия, и поведение VS по умолчанию в этих проектах состоит в том, чтобы поместить весь код в заголовки, что является настолько анти-пимпл, насколько вы можете получить.

Если вы пишете что-то достаточно большое, чтобы гарантировать pimpl, я бы не рекомендовал C++/cli. Если вы пишете что-то достаточно маленькое, чтобы сделать его подходящим для C++/cli, я бы не стал заморачиваться с pimpl.

YMMV, конечно, но это мое мнение...

person Will Dean    schedule 04.12.2008
comment
Что касается поведения VS по умолчанию […]: я не совсем понимаю это. Программист должен вручную создать как файл .h, так и файл .cpp (содержащий только #include файла заголовка) и убедиться, что все определение управляемого класса помещается в файл заголовка. Насколько я знаю, VS вообще не автоматизирует это соглашение. - person stakx - no longer contributing; 28.05.2016

После дальнейшего копания и размышлений я обнаружил, что в некоторых отношениях .NET действительно не нужно поддерживать PIMPL так же, как C++, поскольку вы можете пометить класс как частный для сборки - это, по сути, имеет тот же эффект, в некоторых отношениях. Однако часто идиома PIMPL используется для сокрытия заголовков, которые вы не хотите, чтобы клиент компилировал. Но, конечно, сборки .NET не «включены», как заголовки для C++, поэтому я думаю, что и здесь нет проблем.

person Brian Stewart    schedule 04.12.2008