如何编写这个异常类? [英] How to write this exception class?

查看:59
本文介绍了如何编写这个异常类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了下面的类,但是我的指南告诉我添加一个像
这样的异常类 "MySocketClient.h"并添加了所有这些throw语句.
我不知道如何编写异常类,请为异常类编写伪代码.

I have written the below class but my guide told me to add an exception class like
"MySocketClient.h" and added all these throw statements.
I don''t know how to write the exception class,can you please write the pseudo code for exception class.

//---------------------------------------------------------------------------


#pragma hdrstop

#include "MySocketClient.h"

MySocketClient::MySocketClient() throw(SocketException){
	WSAData data;
	InitializeCriticalSection(§_);
	if(WSAStartup(MAKEWORD(2,2),&data)!=0){
		throw SocketException("Cant load WinSock library");
	}
	connected_=false;
}
//-----------------------------------------------------------------------------

MySocketClient::~MySocketClient(){
	WSACleanup();
}
//-----------------------------------------------------------------------------

void MySocketClient::receive(void){
	char recBuf[1024];
	while(1){
		EnterCriticalSection(§_);
		memset(recBuf,0,1024);
		int recLen=recv(sock_,recBuf,1024,0);
		if(recLen==0){
			onDisconnect(sock_);
			connected_=false;
			break;
		}else if(recLen<0){
			connected_=false;
			onConnectionError(sock_);
			break;
		}else{
			onReceive(sock_,recBuf,recLen);
		}
		LeaveCriticalSection(§_);
	}
}
//------------------------------------------------------------------------------
void MySocketClient::sendData(char *sendBuf,int sendLen) throw(SocketException){
	onSendData(sendBuf,sendLen);
	if(send(sock_,sendBuf,sendLen,0)<0){
		onConnectionError(sock_);
	}
	Sleep(200);
}*191#
//------------------------------------------------------------------------------
void MySocketClient::Connect(string hostname,unsigned short port) throw(SocketException){
	sock_=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if(sock_==INVALID_SOCKET){
		throw SocketException("Cant create socket");
	}
	HOSTENT *host=gethostbyname(hostname.c_str());
	if(host==NULL){
		throw SocketException("Cant resolve host");
	}
	addr_.sin_family=AF_INET;
	addr_.sin_port=htons(port);
	addr_.sin_addr.S_un.S_addr=*(unsigned long*)host->h_addr_list[0];
	if(connect(sock_,(sockaddr*)&addr_,sizeof(sockaddr))==SOCKET_ERROR){
		throw SocketException("Connect Error");
	}
	DWORD dwThreadId;
	threadHandle_=CreateThread(NULL,0,startReceive,this,0,&dwThreadId);
	if(threadHandle_==NULL){
		connected_=false;
		shutdown(sock_,SD_BOTH);
		closesocket(sock_);
		throw SocketException("Receive thread create error");
	}
	connected_=true;
	onConnect(sock_);
}
//------------------------------------------------------------------------------



void MySocketClient::Disconnect(void){
	TerminateThread(threadHandle_,0);
	shutdown(sock_,SD_BOTH);
	closesocket(sock_);
}

		//Virtual functions
void MySocketClient::onReceive(SOCKET sock,char *recBuf,int recLen) throw(SocketException){
}

void MySocketClient::onDisconnect(SOCKET sock){
}

void MySocketClient::onConnectionError(SOCKET sock){
}

void MySocketClient::onSendData(char *sendBuf,int sendLen){

}

void MySocketClient::onConnect(SOCKET sock){
}
#pragma package(smart_init)

推荐答案

一种简单的方法来阐明您的要求异常类,是查看每个throw语句,并想象它是一个return语句.

在这种情况下,所有throw语句看起来都是相同的:它们返回"一个名为SocketException的类的对象,并使用const char*类型的单个参数对其进行初始化.
我没有尝试过,但我认为最简单的解决方案是:
A simple way to clarify the requirements of your exception class, is to look at each throw statement, and imagine it were a return statement instead.

In this case, all throw statements look the same: they "return" an object of a class called SocketException, and initialize it with a single argument of type const char*.

I haven''t tried it but I believe the most simple solution would be:
typedef const char* SocketException;


IE.而不是定义一个新的类,而是使用一个预先存在的类型.但是,如果基于相同的既有类型有多个以上的Exception类型,则可能会出现问题,因为那样一来,您将无法区分这两种类型的错误.

因此,下一个最佳解决方案是:


I. e. rather than define a new class, you use a pre-existing type. However, this could be problematic if you have more than one Exception type based on the same pre-existing type, because then you wouldn''t be able to distinguish between the two types of errors.

So the next best solution would be:

struct SocketException {
   const char* message;
   SocketException(const char* text) {
      message = text;
   }
};


不管将其设为结构还是类都没有关系,但是如果在上面的示例中将成员变量message声明为private,则还需要添加访问器函数.

更好的是一个构造函数,该构造函数不仅可以复制指针,还可以创建字符串的副本.这将允许您使用存储在临时变量中的构造消息引发异常:


Whether you make it a struct or a class doesn''t matter, but if in the above example your member variable message were declared private, you''d need to add an accessor function as well.

Even better would be a constructor that doesn''t simply copy a pointer, but creates a copy of the string. That would allow you to throw an exception with a constructed message that is stored in a temporary variable:

#include <string>
class SocketException {
public:
   std::string message;
   SocketException(const char* text) {
      message = text;
   }
};


void foo() throw SocketException {
   char buffer[30]; // Accessing this with a pointer after leaving the function is an error!
   static int count = 0;
   sprintf(buffer, "foo called %d times!", count);
   ++count;
   throw SocketException(buffer);
}


注意,SocketException对象将在离开函数i之前被构造. e.而buffer仍然可以安全地访问.如果仅存储指针,则访问该消息将导致运行时错误.


Note that the SocketException object will be constructed before leaving the function, i. e. while buffer can still be accessed safely. If you would store only the pointer, accessing the message would cause a run-time error.


这篇关于如何编写这个异常类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆