У меня есть этот код, и я пытаюсь понять сопровождаемую конвенцию, весь метод, определенный в .cpp файле, имеют template<class KeyType, class DataType>
записанный перед ними. Что это означает?
Пример:
//Constructor
template<class key, class type>
MyOperation<key, type>::MyOperation()
{
//method implementation
}
//A method
template<class key, class type>
MyOperation<key, type>::otherOperation()
{
//method implementation
}
Спасибо
Для этого должен быть хороший ответ уже, но я тоже брошу в бассейн.
C ++ допускает раздельное объявление и реализацию структур программы. Это проистекает из того, как программисты C / C ++ публикуют новые функции друг для друга: файлы заголовков включаются в зависимые блоки компиляции, а не в те блоки, которые полагаются на метаданные, присутствующие при компиляции (как и следовало ожидать, если вы работаете с C # или Java).
Каждый раз, когда вы даете компилятору инструкцию, будь то объявление («вот эта штука с этим интерфейсом») или реализация («вот эта штука с этим интерфейсом и этим поведением»), вы есть возможность шаблонизировать эту директиву.
Тот факт, что у вас есть возможность сделать это, а не требование, дает вам гораздо большую гибкость, чем вам предоставляют более современные языки, такие как Java и C #.
Рассмотрим следующий шаблон (я уже ржавый, будьте любезны с небольшими проблемами синтаксиса, пожалуйста):
template<typename Junk>
class IGotJunk {
private:
Junk myJunk_;
public:
void SetJunk(Junk const& source);
Junk const& GetJunk() const;
}
Ваша «типичная» реализация указанного шаблона может включать следующие варианты поведения по умолчанию:
template<typename Junk>
void IGotJunk<Junk>::SetJunk(Junk const& source)
{
myJunk_ = source;
}
Однако для строк существует риск того, что строка будет изменена после копирования указателя, и в этом случае вы можете предоставить специальное поведение, которое гарантирует копирование самой строки, а не указателя (опять же, это было долгое время) ...
void IGotJunk<char*>::SetJunk(char* const& source)
{
free(myJunk_);
myJunk_ = malloc(strlen(source) + 1);
strcpy(myJunk_, source);
}
Затем вы можете сделать что-то подобное для GetJunk (). Вероятно, поэтому вам нужно объявлять параметры шаблона для каждого создаваемого вами артефакта: потому что вы можете не захотеть, чтобы они были одинаковыми во всех случаях.
Это просто означает, что в файле заголовка класс шаблона определен как :
template<class key, class type>
class MyOperation
{
...
};
Итак, когда вы реализуете методы в файле .cpp
, вам необходимо включить параметры шаблона:
template<class key, class type> MyOperation<key, type>::
Как в:
template<class key, class type> MyOperation<key, type>::otherOperation() { ... }
Этот класс является шаблонным - его можно параметризовать по типам. Чтобы создать экземпляр этого класса, вы должны написать, например,
MyOperation<int, int> myop;
Здесь есть достойная статья о шаблонах C ++ . Шаблоны - важная часть C ++, но им нужно очень много времени, чтобы овладеть ими. Большая часть стандартной библиотеки C ++ использует шаблоны (часто известную под неофициальным названием STL). Например, vector
- это шаблон типа T.
Он сообщает компилятору C ++, что объект, следующий за этим объявлением, является шаблоном.
Более конкретно, это означает, что в дальнейшем слова KeyType и DataType являются именами заполнителей для некоторого типа, которые будут очевидны или указаны при вызове метода. В этот момент компилятор берет шаблон, заменяет KeyType и DataType в методе в зависимости от того, что вы используете, и компилирует эту копию.
В примере кода, который вы показываете, шаблонная часть - это класс, поэтому вполне возможно, что методы на самом деле их не используют, но C ++ должен иметь возможность привязать универсальную реализацию метода к классу всякий раз, когда он использовал.