derived templates doesn't link in Visual C++ 6.0
От: Martyn2000  
Дата: 10.11.01 03:23
Оценка:
Привет!

Подскажите, где проблема, pls. Замаялся уже искать. Или может VC++ 6.0 глючит?

=== a.h ===
[vc]
class Event : public CObject {
DECLARE_DYNAMIC( Event );
public:
Event();
virtual ~Event();
};

class Actor {
public:
Actor();
~Actor();
};

template <class T, class C>
class ActorThread : public Actor {
public:
ActorThread();
~ActorThread();
private:
CWinThread* m_thread;
};
[/vc]
=== a.cpp ===
[vc]
#include "a.h"
IMPLEMENT_DYNAMIC( Event, CObject );

template <class T, class C>
ActorThread<T,C>::ActorThread() {
m_thread = AfxBeginThread( RUNTIME_CLASS( T ) );
}

template <class T, class C>
ActorThread<T,C>::~ActorThread() {
m_thread->PostThreadMessage( WM_QUIT );
}
[/vc]

=== b.cpp ===
[vc]
#include "a.h"
ActorThread<MyThread,MyEvent> actor;
[/vc]

При линковке выдается ошибка LNK2001:
b.obj : error LNK2001: unresolved external symbol "public: __thiscall ActorThread<class MyThread,class MyEvent>::~ActorThread<class MyThread,class MyEvent>(void)" (??1?$ActorThread@VMyThread@@VMyEvent@@@@QAE@XZ)
b.obj : error LNK2001: unresolved external symbol "public: __thiscall ActorThread<class MyThread,class MyEvent>::ActorThread<class MyThread,class MyEvent>(void)" (??1?$ActorThread@VMyThread@@VMyEvent@@@@QAE@XZ)

Классы: MyThread : CWinThread и MyEvent : Event есть в других файлах. Они не важны, т.к. ошибка выдаётся на что угодно в качестве параметра темплейта, даже на <CWinThread,CObject>...

Заранее спасибо.
Re: derived templates doesn't link in Visual C++ 6.0
От: Андрей Россия  
Дата: 10.11.01 06:09
Оценка:
Здравствуйте Martyn2000, Вы писали:

M>Привет!


M>Подскажите, где проблема, pls. Замаялся уже искать. Или может VC++ 6.0 глючит?


M>=== a.h ===

M>[vc]
M>class Event : public CObject {
M> DECLARE_DYNAMIC( Event );
M>public:
M> Event();
M> virtual ~Event();
M>};

M>class Actor {

M>public:
M> Actor();
M> ~Actor();
M>};

M>template <class T, class C>

M>class ActorThread : public Actor {
M>public:
M> ActorThread();
M> ~ActorThread();
M>private:
M> CWinThread* m_thread;
M>};
M>[/vc]
M>=== a.cpp ===
M>[vc]
M>#include "a.h"
M>IMPLEMENT_DYNAMIC( Event, CObject );


M>template <class T, class C>
M>ActorThread<T,C>::ActorThread() {
M> m_thread = AfxBeginThread( RUNTIME_CLASS( T ) );
M>}

M>template <class T, class C>

M>ActorThread<T,C>::~ActorThread() {
M> m_thread->PostThreadMessage( WM_QUIT );
M>}

M>[/vc]

M>Заранее спасибо.



Перенеси реализацию ActorThread (то, что я выделил) в файл a.h и все проблемы исчезнут.
Re[2]: derived templates doesn't link in Visual C++ 6.0
От: Аноним  
Дата: 10.11.01 22:05
Оценка:
Здравствуйте Андрей, Вы писали:

А>Здравствуйте Martyn2000, Вы писали:


M>>Привет!


[...skipped...]

А>Перенеси реализацию ActorThread (то, что я выделил) в файл a.h и все проблемы исчезнут.


Не совсем. Я забыл написать, что деструкторы у Actor & ActorThread должны быть виртуальными (иначе смысла нет) :-))). Т.е. конструктор-то я могу перенести в хедер, но толку-то... Впрочем, и это не помогает, тогда компилер начинает ругаться:

=== a.h
[vc]
class Event : public CObject {
DECLARE_DYNAMIC( Event );
public:
Event();
virtual ~Event();
};

class Actor {
public:
Actor();
virtual ~Actor();
};

template <class T, class C>
class ActorThread : public Actor {
public:
ActorThread()
{ m_thread = AfxBeginThread( RUNTIME_CLASS( T ) ); }
virtual ~ActorThread();
private:
CWinThread* m_thread;
};
[/vc]

a.h(19) : error C2039: 'classT' : is not a member of 'CWinThread'
c:\program files\microsoft visual studio\vc98\mfc\include\afxwin.h(3791) : see declaration of 'CWinThread'
a.h(19) : while compiling class-template member function '__thiscall ActorThread<class CWinThread,class CObject>::ActorThread<class CWinThread,class CObject>(void)'
a.h(19) : error C2065: 'classT' : undeclared identifier
a.h(19) : while compiling class-template member function '__thiscall ActorThread<class CWinThread,class CObject>::ActorThread<class CWinThread,class CObject>(void)'

Похоже, что надо искать другое решение, без темплейтов.....
Re[3]: derived templates doesn't link in Visual C++ 6.0
От: Андрей Россия  
Дата: 12.11.01 04:15
Оценка:
Здравствуйте Аноним, Вы писали:

А>Похоже, что надо искать другое решение, без темплейтов.....


Ты смешал ДВЕ проблемы:
1. Реализация шаблонных классов и функций должна быть доступна всем файлам, в которых инстанцируются экземпляры шаблонов. Решение этой проблемы я тебе дал.
2. Твой шаблон работать не будет по той причине, что препроцессор работает раньше компилятора, и он ничего не знает о твоих шаблонах. То есть в макрос RUNTIME_CLASS передается не имя класса Event, а буквально имя параметра шаблона T, а так как макрос RUNTIME_CLASS реализован довольно просто, он присобачивает к T префикс class и пытается найти определение этого класса. Так что у тебя два пути: или искать другое решение или написать свой RUNTIME_CLASS, который бы понимал шаблоны. А виртуальные деструкторы здесь ни при чем. К тому же ты еще и порядок параметров в своем шаблоне перепутал.
Re[4]: derived templates doesn't link in Visual C++ 6.0
От: Martyn2000  
Дата: 12.11.01 15:24
Оценка:
Здравствуйте Андрей, Вы писали:

А>>Похоже, что надо искать другое решение, без темплейтов.....


А>Ты смешал ДВЕ проблемы:

А>1. Реализация шаблонных классов и функций должна быть доступна всем файлам, в которых инстанцируются экземпляры шаблонов. Решение этой проблемы я тебе дал.

Это понятно.

А>2. Твой шаблон работать не будет по той причине, что препроцессор работает раньше компилятора, и он ничего не знает о твоих шаблонах. То есть в макрос RUNTIME_CLASS передается не имя класса Event, а буквально имя параметра шаблона T, а так как макрос RUNTIME_CLASS реализован довольно просто, он присобачивает к T префикс class и пытается найти определение этого класса. Так что у тебя два пути: или искать другое решение или написать свой RUNTIME_CLASS, который бы понимал шаблоны. А виртуальные деструкторы здесь ни при чем. К тому же ты еще и порядок параметров в своем шаблоне перепутал.


Это тоже понятно. Я и не говорил что это та же самая проблема — я говорил что возникает еще одна.

Спасибо за ответы. Я придумал как избавиться от шаблонов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.