我的模板类创建错误会导致 SOCKET 错误,为什么?
我创建了一个类,它保存类型的数据并根据请求返回一个向量。 但不知怎的,出现了以下错误:
error C2259: 'CAcceptor' : cannot instantiate abstract class
due to following members:
'void CDataAndEvent<C>::InitQueue(void)' : is abstract
with
[
C=SOCKET
]
see declaration of 'CDataAndEvent<C>::InitQueue' with
[ C=SOCKET
]
类的代码:
#pragma once
#include <IncStandard.h>
#include <IncWinsock.h>
#include <IncStatus.h>
//Class which hold an Input and Output vector
//and the corresponding events
template<class C>
class CDataAndEvent
{
public:
CDataAndEvent(void);
virtual ~CDataAndEvent(void);
//Access functions
//Vectors
virtual Inc::STATS GetInData(__out std::vector<C>&);
virtual Inc::STATS GetOutData(__out std::vector<C>&);
virtual Inc::STATS AddDataIn(__in const C&);
virtual Inc::STATS AddDataOut(__in const C&);
//Queues
virtual HANDLE GetOutEvent() { return m_hEventOut; };
virtual HANDLE GetInEvent() { return m_hEventIn; };
protected:
//Make this class non-instanceable
virtual void InitQueue() = 0;
private:
//Input-/Output Vector
std::vector<C> m_vecIn;
std::vector<C> m_vecOut;
//Events for the input- and output vector
HANDLE m_hEventIn;
HANDLE m_hEventOut;
//Indicators
bool m_bNewIn;
bool m_bNewOut;
};
template<class C>
CDataAndEvent<C>::CDataAndEvent(void) : m_bNewIn(false), m_bNewOut(false)
{
//create events
m_hEventIn = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hEventOut = CreateEvent(NULL, TRUE, FALSE, NULL);
}
template<class C>
CDataAndEvent<C>::~CDataAndEvent(void)
{
}
template<class C>
Inc::STATS CDataAndEvent<C>::GetOutData(std::vector<C>& vec)
{
if(!m_bNewOut)
return Inc::NEMPTY;
vec = m_vecOut;
m_vecOut.clear();
m_bNewOut = false;
ResetEvent(m_hEventOut);
return Inc::SOK;
}
template<class C>
Inc::STATS CDataAndEvent<C>::GetInData(std::vector<C>& vec)
{
if(!m_bNewIn)
return Inc::NEMPTY;
//copy
vec = m_vecIn;
//clear the read data
m_vecIn.clear();
//no new data
ResetEvent(m_hEventIn);
m_bNewIn = false;
return Inc::SOK;
}
template<class C>
Inc::STATS CDataAndEvent<C>::AddDataOut(const C& str)
{
m_vecOut.push_back(str);
m_bNewOut = true;
SetEvent(m_hEventOut);
return Inc::SOK;
}
template<class C>
Inc::STATS CDataAndEvent<C>::AddDataIn(const C& str)
{
m_vecIn.push_back(str);
//new data available
m_bNewIn = true;
SetEvent(m_hEventIn);
return Inc::SOK;
}
有人知道为什么会发生这种情况吗?...
CAcceptor 类定义如下
#pragma once
#include "connection.h"
#include "DataAndEvent.h"
class CAcceptor :
public CConnection, public CDataAndEvent<SOCKET>
{
public:
CAcceptor(void);
virtual ~CAcceptor(void);
//Bind the port
Inc::STATS BindSocket(const std::string& strPort);
Inc::STATS Start(); //Start accepting
Inc::STATS Stop(); //Stop accepting
private:
//Send data: not needed for the acceptor
Inc::STATS _SendData(sockaddr* pTarget, int tolen, std::string& strData) {return Inc::EUNKNOWN;};
//Recv data: not needed for the acceptor
Inc::STATS _RecvData(sockaddr* pSender, int* tolen, std::string& strData) {return Inc::EUNKNOWN;};
//Create sockets
Inc::STATS CreateSocket();
//Delete Sockets
Inc::STATS DeleteSocket();
//Thread stuff
HANDLE m_hThread; //Thread handle for the auto mode thread
friend DWORD WINAPI AutoModeThread(void*); //Auto mode thread
};
,据我检查,它覆盖了 CConnection 中的纯虚函数:
#pragma once
//Headers
#include <IncStatus.h>
#include <IncWinsock.h>
#include <IncStandard.h>
class CConnection
{
public:
CConnection();
virtual ~CConnection(void);
//TEST: Bind socket contained by m_mapSocketContainer
virtual Inc::STATS BindSocket(const std::string& strPort) = 0;
//Resolve Target Address
addrinfo* ResolveAddress(const std::string& strAddress, const std::string& strPort);
protected:
//Sockets
SOCKET m_Socket;
//Target Address
addrinfo* m_pTargetAddress;
//Socket
//Creates the sockets needed
//Will be called automatically by the constructor
virtual Inc::STATS CreateSocket() = 0;
//closes the sockets
//Will be called automatically by the destructor
virtual Inc::STATS DeleteSocket() = 0;
//Data Transmission User Request
virtual Inc::STATS _SendData(sockaddr* pTarget, int tolen, std::string& strData) = 0;
virtual Inc::STATS _RecvData(sockaddr* pSender, int* fromlen, std::string& strData) = 0;
private:
//Winsock startup & cleanup
//Start / Stop
Inc::STATS StartWinsock();
Inc::STATS StopWinsock();
WSADATA m_Wsa;
unsigned short m_wWsaVer;
static bool bWinsockRunning;
};
谢谢! ...
I created a class which holds data of type and returns an vector on request.
But somehow the following error occurs:
error C2259: 'CAcceptor' : cannot instantiate abstract class
due to following members:
'void CDataAndEvent<C>::InitQueue(void)' : is abstract
with
[
C=SOCKET
]
see declaration of 'CDataAndEvent<C>::InitQueue' with
[ C=SOCKET
]
code for the class:
#pragma once
#include <IncStandard.h>
#include <IncWinsock.h>
#include <IncStatus.h>
//Class which hold an Input and Output vector
//and the corresponding events
template<class C>
class CDataAndEvent
{
public:
CDataAndEvent(void);
virtual ~CDataAndEvent(void);
//Access functions
//Vectors
virtual Inc::STATS GetInData(__out std::vector<C>&);
virtual Inc::STATS GetOutData(__out std::vector<C>&);
virtual Inc::STATS AddDataIn(__in const C&);
virtual Inc::STATS AddDataOut(__in const C&);
//Queues
virtual HANDLE GetOutEvent() { return m_hEventOut; };
virtual HANDLE GetInEvent() { return m_hEventIn; };
protected:
//Make this class non-instanceable
virtual void InitQueue() = 0;
private:
//Input-/Output Vector
std::vector<C> m_vecIn;
std::vector<C> m_vecOut;
//Events for the input- and output vector
HANDLE m_hEventIn;
HANDLE m_hEventOut;
//Indicators
bool m_bNewIn;
bool m_bNewOut;
};
template<class C>
CDataAndEvent<C>::CDataAndEvent(void) : m_bNewIn(false), m_bNewOut(false)
{
//create events
m_hEventIn = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hEventOut = CreateEvent(NULL, TRUE, FALSE, NULL);
}
template<class C>
CDataAndEvent<C>::~CDataAndEvent(void)
{
}
template<class C>
Inc::STATS CDataAndEvent<C>::GetOutData(std::vector<C>& vec)
{
if(!m_bNewOut)
return Inc::NEMPTY;
vec = m_vecOut;
m_vecOut.clear();
m_bNewOut = false;
ResetEvent(m_hEventOut);
return Inc::SOK;
}
template<class C>
Inc::STATS CDataAndEvent<C>::GetInData(std::vector<C>& vec)
{
if(!m_bNewIn)
return Inc::NEMPTY;
//copy
vec = m_vecIn;
//clear the read data
m_vecIn.clear();
//no new data
ResetEvent(m_hEventIn);
m_bNewIn = false;
return Inc::SOK;
}
template<class C>
Inc::STATS CDataAndEvent<C>::AddDataOut(const C& str)
{
m_vecOut.push_back(str);
m_bNewOut = true;
SetEvent(m_hEventOut);
return Inc::SOK;
}
template<class C>
Inc::STATS CDataAndEvent<C>::AddDataIn(const C& str)
{
m_vecIn.push_back(str);
//new data available
m_bNewIn = true;
SetEvent(m_hEventIn);
return Inc::SOK;
}
Anyone got a clue why this happens?...
The CAcceptor-class is defined as the following
#pragma once
#include "connection.h"
#include "DataAndEvent.h"
class CAcceptor :
public CConnection, public CDataAndEvent<SOCKET>
{
public:
CAcceptor(void);
virtual ~CAcceptor(void);
//Bind the port
Inc::STATS BindSocket(const std::string& strPort);
Inc::STATS Start(); //Start accepting
Inc::STATS Stop(); //Stop accepting
private:
//Send data: not needed for the acceptor
Inc::STATS _SendData(sockaddr* pTarget, int tolen, std::string& strData) {return Inc::EUNKNOWN;};
//Recv data: not needed for the acceptor
Inc::STATS _RecvData(sockaddr* pSender, int* tolen, std::string& strData) {return Inc::EUNKNOWN;};
//Create sockets
Inc::STATS CreateSocket();
//Delete Sockets
Inc::STATS DeleteSocket();
//Thread stuff
HANDLE m_hThread; //Thread handle for the auto mode thread
friend DWORD WINAPI AutoModeThread(void*); //Auto mode thread
};
and as far as i checked it overrides the pure virtual functions from CConnection:
#pragma once
//Headers
#include <IncStatus.h>
#include <IncWinsock.h>
#include <IncStandard.h>
class CConnection
{
public:
CConnection();
virtual ~CConnection(void);
//TEST: Bind socket contained by m_mapSocketContainer
virtual Inc::STATS BindSocket(const std::string& strPort) = 0;
//Resolve Target Address
addrinfo* ResolveAddress(const std::string& strAddress, const std::string& strPort);
protected:
//Sockets
SOCKET m_Socket;
//Target Address
addrinfo* m_pTargetAddress;
//Socket
//Creates the sockets needed
//Will be called automatically by the constructor
virtual Inc::STATS CreateSocket() = 0;
//closes the sockets
//Will be called automatically by the destructor
virtual Inc::STATS DeleteSocket() = 0;
//Data Transmission User Request
virtual Inc::STATS _SendData(sockaddr* pTarget, int tolen, std::string& strData) = 0;
virtual Inc::STATS _RecvData(sockaddr* pSender, int* fromlen, std::string& strData) = 0;
private:
//Winsock startup & cleanup
//Start / Stop
Inc::STATS StartWinsock();
Inc::STATS StopWinsock();
WSADATA m_Wsa;
unsigned short m_wWsaVer;
static bool bWinsockRunning;
};
Thank You!...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从类模板
CDataAndEvent
派生的所有类(包括CAcceptor
)都需要定义InitQueue()
(这是一个纯虚函数,使得该类模板是抽象的)。尽管在您发布的代码中我没有看到任何CAcceptor::InitQueue
定义。All classes derived from the class template
CDataAndEvent<T>
includingCAcceptor
needs to defineInitQueue()
(which is a pure virtual function making the class template an abstract one). I don't see anyCAcceptor::InitQueue
definition though in the code you posted.