[C++]Как правильно использ. уже определенный в другом файле шаблон?
а в .cpp только реализацию
шаблоны тут ни при чем
ты сначала добейся работы без шаблонов, просто с классом
// A.cpp
void A::f
{
// реализация функции 1
}
void A::g
{
// реализация функции 2
}
// A.h
// описание класса
class A
{
public void f;
public void g;
}
// main.cpp
include "A.h"
new A; // использование
Спасибо, мысль понятна. Но ты в файле A.cpp определяешь ф-и, которые используешь в A.h. Почему же нельзя так делать с классами (или шаблонами классов)?
Потому что работать с классом ты можешь вне зависимости от того, имеешь ли ты исходный код его реализации. А чтобы из шаблонов сгенерить классы, ты должен знать исходник. И чтобы пользоваться шаблонами, твой main.cpp должен знать, что же из них реально получилось. Что-то в этом духе.
и в случае Managed C++ то же самое?
Потому что если бы в теме было сразу ясно указано, что за язык, я бы даже не полез в нее, а так я уже собрался было ответить, а тут облом.
и в случае Managed C++ то же самое?конечно, MC++ имеют все ограничения обычных плюсов
Есть мнение, что в заголовки стоит писать не C++, а Managed C++, а еще лучше C++/CLI.данный вопрос ни какого отношения к mc++ не имеет.
вопрос касается обычных проблем плюсов.
ps
MC++ кстати очень хорошо сделан, в духе оригинальных C++.
данный вопрос ни какого отношения к mc++ не имеет.вопрос касается обычных проблем плюсов.Вполне возможно, но, поскольку в MC++ я абсолютно некомпетентен, а код там приведен именно для него, то и ответить мне нечего, и читать оказалось не интересно.
в какой это строчке кода?
этот код должен собираться в любом компиляторе C++ с такими же проблемами.
int main(array<System::String ^> ^args)
сначала не заметил крышек, но этот код по синтаксису полностью эквивалентен
int main(array<System::String *> *args)
крышка только обозначает, что указатель обрабатывается GC
сначала не заметил крышек, но этот код по синтаксису полностью эквивалентенint main(array<System::String *> *args)Ага, а что такое в С++ array?
Ну, разве что по виду это похоже на какой-то шаблон, но вообще это ключевое слово, по-моему, о котором я также ничего не знаю.
то есть, в MC++ дженерики не поддерживаются?
Ага, а что такое в С++ array?очевидно, что что-то такое:
#include "array.h"
ps
по смыслу обычный шаблонный класс
Компоновщик, который вызывается после компиляции всех файлов с исходным кодом, просматривает результаты компиляции и, как из кирпичей, собирает программу, вставляя на место сигнатур соответствующие вызовы.
Следует обратить внимание на то, что компоновщик ничего не знает ни о классах, ни о шаблонах. С ними работает исключительно компилятор. Поэтому если в некотором месте кода используется хоть какая-то информация о классе X (кроме того, что идентификатор X обозначает некоторый класс то необходимо, чтобы к этому моменту было известно определение класса. Если достаточно лишь информации о том, что X является некоторым классом, то можно ограничиться объявлением:
class X;
С шаблонами еще интереснее. Компилятор может сгенерировать код для каждой функции из шаблонного класса только при условии того, что ему известны все входящие в нее типы (и прочие параметры шаблона, если такие есть). Если описание этих функций включено в .h-файл, то никаких проблем нет - компилятору известно, с какими параметрами будет использоваться шаблон, и для каждого использованного набора этих параметров он сгенерирует необходимый код (процедура генерации кода для заданного набора параметров шаблона называется инстанцированием). Если описание функций включено в отдельный файл x.cpp, а шаблон класса - в файл x.h, то компилятор ошибок выдавать не будет как при компиляции файла x.cpp, так и при компиляции некоторого файла a.cpp, использующего этот шаблон, - все необходимые объявления присутствуют. Ошибки будут на стадии компоновки. Дело в том, что при компиляции x.cpp компилятор не знает, с какими наборами параметров будет использоваться шаблон (так как он используется только в файле a.cpp). И поскольку в файле x.cpp этот шаблон не используется ни с каким набором параметров, то компилятор вообще никакого кода не сгенерирует! А при компиляции файла a.cpp компилятор не имеет исходного кода вызываемых функций, поэтому также их не скомпилирует, но вызовы правильно оформит, так как объявления этих функций ему доступны; то есть он сможет инстанцировать класс, но не сможет инстацировать функции-члены этого класса.
Если громоздкий код функций не хочется вставлять в .h-файл, то есть другое решение, называемое явным инстанцированием шаблона. Суть его заключается в том, что в .cpp-файл со всеми описаниями функций вставляется инструкция наподобие следующей
template class X<double>;
которая указывает компилятору, что описанные функции необходимо инстанцировать для типа double. Этих инструкций может быть несколько (с различными наборами параметров тогда инстанцирование будет выполнено для каждого указанного набора.
Некоторые детали я здесь опустил (и все равно простыня получилась но вроде ничего существенного не забыл.
Оставить комментарий
zrab
Так вот: в файле main.cpp я попытался вызвать конструктор класса А (public, не private а компилятор ругается. В литературе написано, что в файле file1.h надо писать не
,а
но компилятор опять ругается. В чем причина?
Что самое главное - с шаблонами функций все получалось нормально.