|
Server Help Community forums for Subgame, ASSS, and bots
|
Author |
Message |
Samapico No, these DO NOT look like penises, ok?
Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Mon Sep 28, 2009 1:28 am Post subject: C++ : Inheritance,Template and Threads problems |
|
|
|
|
I have a class (Layer) from which another class (Layer_net) inherits. Other classes will inherit from it eventually.
I made the Layer class a template because there is a specific data type that I want to specify for each child class.
I'm having problems to define class functions outside the class body. They compile fine, but the linker freaks out when one of the function appears in the code.
#define T_LAYER template <typename T>
T_LAYER
class Layer
{
public:
//stuff...
void Func1();
void Func2() { printf("hi, this is Func2\n"); }
};
T_LAYER
void Layer<T>::Func1()
{
printf("hi, this is Func1\n");
}
//meanwhile, in another class not far away...
struct HeaderNetwork
{
char ip[4];
};
class Layer_net : public Layer<HeaderNetwork>
{
public:
//stuff
};
//and in the main...
int main(void)
{
Layer_net net;
net.Func1();
net.Func2();
}
|
Ok, it seems the above code works if you put it all in the same file.
I then split it up in a header file and 2 cpp's like so:
header.h
#include <stdio.h>
#include <stdlib.h>
struct HeaderNetwork
{
char ip[4];
};
template <typename T>
class Layer
{
public:
//stuff...
void Func1(int);
void Func2() { printf("hi, this is Func2\n"); }
};
//meanwhile, in another class not far away...
class Layer_net : public Layer<HeaderNetwork>
{
public:
//stuff
};
|
layer.cpp
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
template <typename T>
void Layer<T>::Func1(int a)
{
printf("hi, this is Func1\n");
}
|
main.cpp
#include "header.h"
//and in the main...
int main(void)
{
Layer_net net;
net.Func1(1);
net.Func2();
getchar();
} |
Build results:
1>------ Build started: Project: test, Configuration: Debug Win32 ------
1>Compiling...
1>main.cpp
1>Generating Code...
1>Compiling...
1>layer.cpp
1>Generating Code...
1>Linking...
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall Layer<struct HeaderNetwork>::Func1(int)" (?Func1@?$Layer@UHeaderNetwork@@@@QAEXH@Z) referenced in function _main
1>D:\Sam\Prog Projects\GPA785\trunk\Debug\test.exe : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://d:\Sam\Prog Projects\GPA785\trunk\test\Debug\BuildLog.htm"
1>test - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Can anyone figure out what's happening?
Using Visual Studio 2005 _________________ (Insert a bunch of dead links here)
Last edited by Samapico on Mon Sep 28, 2009 2:22 am, edited 1 time in total |
|
Back to top |
|
|
Samapico No, these DO NOT look like penises, ok?
Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Mon Sep 28, 2009 2:00 am Post subject: |
|
|
|
|
I think I found my answer
http://cpp.developpez.com/faq/cpp/?page=templates#DIVERS_templates
(in french)
Basically, for some reason I have to make the layer.cpp NOT compile, and instead of including the header in it, I must include the cpp at the end of the header file...
I don't really understand why, but it works |
|
Back to top |
|
|
Samapico No, these DO NOT look like penises, ok?
Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Mon Sep 28, 2009 2:21 am Post subject: |
|
|
|
|
I have another somewhat related problem, and I'm pretty tired now, so excuse me if it's dumb:
Still in my template class, I got some function declared:
DWORD WINAPI threadloop(LPVOID iValue);
and defined later.
And then I want to create a thread in there...
First try:
hthread = CreateThread(NULL, 0, threadloop, "", 0, &threadID); | error C3867: 'Layer<T>::threadloop': function call missing argument list; use '&Layer<T>::threadloop' to create a pointer to member
Ok... second try:
hthread = CreateThread(NULL, 0, &Layer<T>::threadloop, "", 0, &threadID); | error C2664: 'CreateThread' : cannot convert parameter 3 from 'DWORD (__stdcall Layer<T>::* )(LPVOID)' to 'LPTHREAD_START_ROUTINE'
And then I desperately tried to typecast it:
hthread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(&Layer<T>::threadloop), "", 0, &threadID); |
It failed.
A lot of stuff in there looks weird to me, but I started from an example given by the teacher... but yeah, he wasn't using templates, obviously |
|
Back to top |
|
|
Doc Flabby Server Help Squatter
Joined: Feb 26 2006 Posts: 636 Offline
|
Posted: Mon Sep 28, 2009 5:05 am Post subject: |
|
|
|
|
I recommend looking at pthreads or using a C++ framework. Working directly with the Windows API is a PITA but anyways:
hthread = CreateThread(NULL, 0, &Layer<T>::threadloop, "", 0, &threadID);
|
The problem here is the compiler does not know what T is. Creating an instance of the class Layer<T> and pass it to the function might fix this problem.
eg,
Layer<int> t = new Layer<int>;
hthread = CreateThread(NULL, 0, &t::threadloop, "", 0, &threadID);
|
This might not work btw
I'm not overally familier with templates (i've not used them) in C++ but this link might help http://docs.google.com/gview?a=v&q=cache:twJe98TSVCIJ:www.allankelly.net/static/writing/overload/Threads/ThreadTemplate.pdf+templates+theading&hl=en&gl=uk&sig=AFQjCNEN1kd0XAxuQ2BA4Gq6xtyPrEfVsA[/code] _________________ Rediscover online gaming. Get Subspace | STF The future...prehaps |
|
Back to top |
|
|
Samapico No, these DO NOT look like penises, ok?
Joined: May 08 2003 Posts: 1252 Offline
|
|
Back to top |
|
|
Doc Flabby Server Help Squatter
Joined: Feb 26 2006 Posts: 636 Offline
|
Posted: Mon Sep 28, 2009 10:44 am Post subject: |
|
|
|
|
You would think it would, but it is C++ after all
I found the source for that link which has threads created inside Templates (go to bottom of the page)
http://www.allankelly.net/writing/softdesign.html
http://www.allankelly.net/static/writing/overload/Threads/threadssource.zip
From the source (snippit) you can see its a bit of a hack job Essentially you have to pass the RunThread an object that implements a "run" function (this might sound familier )
void RunThread( T &x,
long stackSize = 0)
{
// each object represents one thread
// therefore, should not launch multiple threads with one object
assert (NULL == m_threadHandle);
// other parameters may be dafaulted if needed
DWORD dwStack = (DWORD) stackSize;
// create a thread
m_threadHandle = CreateThread(
NULL, // pointer to thread security attributes
dwStack, // initial thread stack size, in bytes
StartRun, // pointer to thread function
&x, // argument for new thread
0, // creation flags
&m_threadId); // pointer to returned thread identifier
DWORD last = GetLastError(); // useful for debug stepping
if (NULL == m_threadHandle)
{
throw std::runtime_error("Failed to start thread");
}
}
static unsigned long __stdcall StartRun(void *param)
{
T* object = static_cast<T*> (param); // reclaim object type
object->Run();
return 0;
}
|
|
|
Back to top |
|
|
Samapico No, these DO NOT look like penises, ok?
Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Mon Sep 28, 2009 7:10 pm Post subject: |
|
|
|
|
hmmmm, but the argument of RunThread would still have to be of type Layer<T>, since I want the Run() function to be in there
Not sure how to translate this in my project... |
|
Back to top |
|
|
Dr Brain Flip-flopping like a wind surfer
Age:38 Gender: Joined: Dec 01 2002 Posts: 3502 Location: Hyperspace Offline
|
Posted: Mon Sep 28, 2009 7:32 pm Post subject: |
|
|
|
|
This is why C++ always seems horrible to me. Simple, easy things are complicated and non-intuitive. You use it if you have to, but stay away from it otherwise. _________________ Hyperspace Owner
Smong> so long as 99% deaths feel lame it will always be hyperspace to me |
|
Back to top |
|
|
Samapico No, these DO NOT look like penises, ok?
Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Mon Sep 28, 2009 10:54 pm Post subject: |
|
|
|
|
I could go the easy way and get rid of the template, that would just give me some copy paste to do |
|
Back to top |
|
|
Samapico No, these DO NOT look like penises, ok?
Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Thu Oct 01, 2009 11:57 am Post subject: |
|
|
|
|
Samapico wrote: | I could go the easy way and get rid of the template, that would just give me some copy paste to do | Oh well... I went the easy way
I didn't actually need the members of the type in the base class, I only needed to know the sizeof it to allocate memory and such. So I just used an int for the size, and initialize it to sizeof(MyHeader) in the derived class.
F*** templates. |
|
Back to top |
|
|
|
|
You can post new topics in this forum You can reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You can attach files in this forum You can download files in this forum
|
Software by php BB © php BB Group Server Load: 660 page(s) served in previous 5 minutes.
|