Шаблоны и файлы .cpp - PullRequest
       1

Шаблоны и файлы .cpp

0 голосов
/ 15 января 2012

Я изучаю C ++, и это не было приятным опытом (по крайней мере, по сравнению с Java или VBA). У меня есть следующий код:

//This is in a number.h file
  #pragma once
  template <class T>
  class number{
        public: 
               T value1, value2, result; 
        public: 
               T add();
               number(T value1_in, T value2_in);
  };

 //This is in a number.cpp file
   template <class T>
   number<T>::number(T value1_in, T value2_in){
              value1 = value1_in;
              value2 = value2_in;
   }

   template <class T>
   T number<T>::add(){
   result = value1 + value2; 
   return result; 
   }

 //This is in main.cpp
   #include "number.h"
   #include <iostream>
   using namespace std;

   int main(){
       int a = 2, b =3;

       number<int> n1(a,b);
       cout << n1.add();
       system("pause");
       return EXIT_SUCCESS;
  }

Что, конечно, дает мне ошибку. Хотя я почти уверен, что это должно сработать. Более конкретно я получаю ошибку компоновщика. После 3 часов просмотра я решил включить number.cpp в main.cpp, и это волшебным образом заставило его работать. Что, черт возьми, происходит? Я думал, что мне нужно только включить файл заголовка (я написал матричный класс с кучей линейных решателей для разных алгоритмов до этого и включил только файлы заголовков во весь проект). Это специфично для C ++ или для компилятора? (Я использую Dev-C ++ 4.9.9.2 с Mingw, я думаю)

Ответы [ 3 ]

3 голосов
/ 15 января 2012

Вы не должны поместить все определение в заголовочный файл; не слушай то, что тебе говорят другие: -)

Это обычное решение, и мы с вами будем делать это довольно часто, но это не единственное решение.

Другой вариант - просто поместить эту строку в end вашего файла number.cpp, чтобы заставить этот конкретный класс шаблона создаваться и полностью компилироваться там.

template class number<int>;

Короче говоря, есть два правильных решения. Вы можете использовать эту строку, или вы можете скопировать определение в заголовочный файл. В зависимости от контекста один подход может быть лучше другого, но оба они действительны. Смотрите мой ответ для более полного обсуждения обоих подходов:

https://stackoverflow.com/a/8752879/146041

3 голосов
/ 15 января 2012

Шаблонные классы или функции всегда должны оставаться в заголовочном файле.

Причина в том, что всякий раз, когда вы создаете экземпляр шаблона, препроцессор (внутри компилятора) генерирует новый код именно для этого типа создания экземпляров (например, number<double>).Вот почему классы number<double> и number<int> не будут иметь никаких отношений: они будут двумя совершенно разными классами, хотя оба были сгенерированы из одного и того же шаблона.

Чтобы компилятор мог генерировать этот код,он должен знать все определение шаблона, а не только его объявление.Вот почему шаблон должен оставаться в заголовке полностью.

Включение файла cpp в ваш main.cpp помогло, так как он фактически стал заголовком.

2 голосов
/ 15 января 2012

В C ++ шаблоны соответствуют тому, что их имя предлагает: шаблоны для класса, функции и т. Д. Поскольку конкретный тип параметра шаблона заранее неизвестен, а скомпилированный объектный код зависит от фактического параметра, они не являютсякомпилирование (как обычные классы и функции) до тех пор, пока вы не используете их в любом другом исходном файле, и компилятор не узнает, какой тип он должен подставить в параметр шаблона.

Вот почему все функции должны быть определены и реализованы вфайл заголовка.См. Последний раздел этой документации или ответы на этого похожего вопроса для дальнейшего объяснения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...