Рассмотрите следующие файлы заголовков.Как компилятор генерирует определения класса шаблонов?
В моем Object.h
#ifndef OBJECT_H_
#define OBJECT_H_
#include <iostream>
template <class Policy>
class Object
{
friend Policy;
private:
Policy* p;
int hash;
public:
Object():p(new Policy(this)),hash(0){}
~Object(){delete p;}
void set(){p->setHash();}
void show() const{std::cout<<"hash = "<<hash<<std::endl;}
};
#endif // OBJECT_H_
Затем я создал две политики, P1 и P2, с различными значениями хэша.
В p1.h
#ifndef P1_H_
#define P1_H_
template <class Policy> class Object;
class P1
{
enum {p1 = 1};
Object<P1>* t;
public:
P1(Object<P1>* at):t(at){}
void setHash(){t->hash = p1;}
};
#endif // P1_H_
В p2.h
#ifndef P2_H_
#define P2_H_
template <class Policy> class Object;
class P2
{
enum {p2 = 2};
Object<P2>* t;
public:
P2(Object<P2>* at):t(at){}
//void setHash(){t->hash = p2;} // ** Notice here **
};
#endif // P2_H_
В моей main.cpp
меня
#include "Object.h"
#include "p1.h"
#include "p2.h"
int main()
{
Object<P1> t1;
t1.set();
t1.show();
Object<P2> t2;
//t2.set();
t2.show();
}
Результат на OS X:
хэш = 1
хэш = 0
Наблюдения:
Он будет компилировать и работать правильно. Обратите внимание, что определение
Object<P2>
еще не завершено. Поскольку P2 не определили setHash().Если я избавлюсь от комментария в моей основной, то он сообщит об ошибке.
./Object.h:20:8: ошибка: ни один член с именем 'setHash' в 'P2'
main.cpp: 12: 6: Примечание: в конкретизации функции члена «Object :: набор 'запрошен здесь t2.set();
Вопросы
Рассмотрим элемент объекта внутри P1 или класса P2 бы компилятор генерировать определение класса для каждого из них, даже если я не создаю экземпляр
Object<P1>
илиObject<P2
в основной?Почему
Object<P2>
в порядке? Поскольку определение неполное.
"тогда он сообщит об ошибке" Что? – user657267
@ пользователь657267 выше. – Ling