Я столкнулся со следующим раздражающим и, казалось бы, некорректным поведением в компиляторе Visual Studio 2008 C ++:
Предположим, у меня есть библиотека классов - Car.lib, которая использует класс "Car", сзаголовок под названием "Car.h":
class Car
{
public:
void Drive()
{
Accelerate();
}
void Accelerate();
};
На самом деле я пытаюсь использовать заголовки Car (для некоторых других функций), но без необходимости связываться с самим Car.lib (фактическимкласс не называется "Car", но я очищаю этот пример).
Если я #include "Car.h" в файле .cpp, который используется для создания управляемого C ++ .dll, но никогда не ссылаюсь на Car,все компилируется и ссылки нормально.Это потому, что я никогда не создаю экземпляр объекта Car.
Однако, следующее:
namespace {
class Car
{
public:
Car(const Car& rhs)
{
Accelerate();
}
void Accelerate();
};
}
оставляет меня с ошибкой связи:
Error 2 error LNK2001: unresolved external symbol "public: void __thiscall `anonymous namespace'::Car::Accelerate(void)" (?Accelerate@Car@?A0xce3bb5ed@@$$FQAEXXZ) CREObjectWrapper.obj CREObjectBuilderWrapper
Примечаниеобъявил все это в анонимном пространстве имен, так что ни в коем случае нельзя экспортировать функции Car из .DLL.
Я могу категорически гарантировать, что Car нигде больше не упоминается, потому что я только что сделал этокласс и набрал в определении от Scatch.«Настоящий» класс - это другое имя.
Объявление конструктора копирования вне строки не имеет значения.то есть следующее также не может связать:
class Car
{
public:
Car(const Car& rhs);
void Accelerate();
};
Car::Car(const Car& rhs)
{
Accelerate();
}
Это что-то особенное, что связано с примечанием конструктора копирования, потому что следующее, например, делает ссылку:
class Car
{
public:
Car()
{
Accelerate();
}
void Accelerate();
};
Я не гуру стандартов C ++, но мне это кажется неправильным.Конечно, компилятору по-прежнему не нужно было даже генерировать какой-либо код, который вызывает конструктор Car copy.
Может кто-нибудь подтвердить, правильно ли это поведение?Прошло много времени с тех пор, как я использовал C ++ - но я не думаю, что это, например, проблема с Visual Studio 6.0.
Это может быть потому, что я создаю управляемый C ++ .dll. (Позже: да, именно в этом проблема. Параметр / clr вводит эту зависимость).
Вот командная строка, используемая для создания проекта:
/OUT:"..\..\bin\Release\CREObjectBuilderWrapper.dll" /INCREMENTAL:NO /NOLOGO /LIBPATH:"..\..\lib\qa\lib" /LIBPATH:"..\..\lib\release" /LIBPATH:"..\..\lib\VDB" /DLL /MANIFEST /MANIFESTFILE:"Release\ObjectBuilderWrapper.dll.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"c:\Release\ObjectBuilderWrapper.pdb" /LTCG /DYNAMICBASE:NO /FIXED:No /MACHINE:X86 /KEYFILE:"c:\src\ObjectBuilderWrapper\\FI.snk" /ERRORREPORT:PROMPT CRERuntime.lib QA.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
Может кто-нибудь предложить обходной путь, который позволяет «повторно использовать» метод Accelerate из конструктора копирования и при этом конструктор копирования объявлен встроенным?