将对象作为异常抛出时的问题:保持父异常类的相同构造方法

时间:2019-06-02 19:51:03

标签: c++ exception

作为我的第一个C ++程序,我决定基于C的先前知识并利用POSIX套接字API创建一个简单的TCP服务器:

因此,我制作了以下头文件network.h

#ifndef HTTP_NETWORK
#define HTTP_NETWORK

#include<string>
#include <arpa/inet.h>

//Dummy Value to be changed
#define MAXPENDING 5

class Exception {
    public:
    Exception(std::string message):message(message){}
    std::string getMessage();
    private:
    std::string message;
};

class NetworkException:public Exception {};

class TCPServer{
    public:
    TCPServer(int port,std::string address);
    ~TCPServer();
    void listen();
    private:
    int port;
    //Socket file Descriptor
    int servSock;
    struct sockaddr_in ServAddr;
};
#endif

然后我制作了network.cpp

#include"network.h"

#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#include<iostream>
#include<cstring>
#include<string>


std::string Exception::getMessage(){
    return this->message;
}

TCPServer::TCPServer(int port,std::string address)
:port(port){

    if ((this->servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        throw NetworkException(std::string("SOCKET Error: could not create basic socket"));
    }

    memset(&this->ServAddr,0,sizeof(this->ServAddr));

    ServAddr.sin_family = AF_INET;
    ServAddr.sin_addr.s_addr = inet_addr(address.c_str());
    ServAddr.sin_port = htons(port);


    if (bind(this->servSock, (struct sockaddr *) &this->ServAddr, sizeof(this->ServAddr)) < 0) {
        throw NetworkException(std::string("SOCKET Error: Failed to bind a socket"));
    }

    if (::listen(this->servSock, MAXPENDING) < 0) {
        throw NetworkException(std::string("SOCKET Error: Failed to Listen"));
    }
}

void TCPServer::listen(){

    struct sockaddr_in ClntAddr;     /* Client address */
    socklen_t clntLen= (socklen_t)sizeof(ClntAddr);
    int clntSock;                    /* Socket descriptor for client */
    //@todo Dummy Logic Depedency Inject Socket Handler
    for (;;) {
       if ((clntSock = accept(servSock, (struct sockaddr *) &ClntAddr, &clntLen)) < 0) {
           std::cout<<"Failed to fetch"<<std::endl;
       }

       send(clntSock, "12345\n", 6, 0);

       std::cout << "Handling client %s\n" << inet_ntoa(ClntAddr.sin_addr) << std::endl;
       close(clntSock);
    }
}

TCPServer::~TCPServer(){
 close(this->servSock);
}

但是以某种方式,我很难抛出一个对象作为异常:

./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(const NetworkException&)
 class NetworkException:public Exception {};
       ^~~~~~~~~~~~~~~~
./src/socket/network.h:18:7: note:   no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const NetworkException&’
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(NetworkException&&)
./src/socket/network.h:18:7: note:   no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘NetworkException&&’
./src/socket/network.cpp:31:84: error: no matching function for call to ‘NetworkException::NetworkException(std::__cxx11::string)’
         throw NetworkException(std::string("SOCKET Error: Failed to bind a socket"));
                                                                                    ^
In file included from ./src/socket/network.cpp:1:0:
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(const NetworkException&)
 class NetworkException:public Exception {};
       ^~~~~~~~~~~~~~~~
./src/socket/network.h:18:7: note:   no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const NetworkException&’
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(NetworkException&&)
./src/socket/network.h:18:7: note:   no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘NetworkException&&’
./src/socket/network.cpp:35:77: error: no matching function for call to ‘NetworkException::NetworkException(std::__cxx11::string)’
         throw NetworkException(std::string("SOCKET Error: Failed to Listen"));
                                                                             ^
In file included from ./src/socket/network.cpp:1:0:
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(const NetworkException&)
 class NetworkException:public Exception {};
       ^~~~~~~~~~~~~~~~
./src/socket/network.h:18:7: note:   no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const NetworkException&’
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(NetworkException&&)
./src/socket/network.h:18:7: note:   no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘NetworkException&&’

首先,我很难将Exception类扩展到更具体的内容。通常以其他语言提供了一个通用类,我可以将其作为异常抛出。在C ++ AFAIK中,任何类型都可以抛出错误,因此我决定要抛出一个类。

但是目前,该计划适得其反,我发现自己很难使用NetworkException的匿名对象,我还尝试通过以下方式更改NetworkException来缓解此问题:

class NetworkException:public Exception {
    public:
    NetworkException(std::string message){}
};

仍然出现错误:

In file included from ./src/main.cpp:4:0:
./src/socket/network.h: In constructor ‘NetworkException::NetworkException(std::__cxx11::string)’:
./src/socket/network.h:20:42: error: no matching function for call to ‘Exception::Exception()’
     NetworkException(std::string message){}
                                          ^
./src/socket/network.h:12:5: note: candidate: Exception::Exception(std::__cxx11::string)
     Exception(std::string message):message(message){}
     ^~~~~~~~~
./src/socket/network.h:12:5: note:   candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(const Exception&)
 class Exception {
       ^~~~~~~~~
./src/socket/network.h:10:7: note:   candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(Exception&&)
./src/socket/network.h:10:7: note:   candidate expects 1 argument, 0 provided
In file included from ./src/socket/network.cpp:1:0:
./src/socket/network.h: In constructor ‘NetworkException::NetworkException(std::__cxx11::string)’:
./src/socket/network.h:20:42: error: no matching function for call to ‘Exception::Exception()’
     NetworkException(std::string message){}
                                          ^
./src/socket/network.h:12:5: note: candidate: Exception::Exception(std::__cxx11::string)
     Exception(std::string message):message(message){}
     ^~~~~~~~~
./src/socket/network.h:12:5: note:   candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(const Exception&)
 class Exception {
       ^~~~~~~~~
./src/socket/network.h:10:7: note:   candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(Exception&&)
./src/socket/network.h:10:7: note:   candidate expects 1 argument, 0 provided

1 个答案:

答案 0 :(得分:2)

您需要调用基类的构造函数:

if is_int ${total} ; then
    # perform some action 
fi

在执行派生类的主体之前,必须构造所有数据成员。 class NetworkException:public Exception { public: NetworkException(std::string message) : Exception(message) {} }; 只有一个带字符串的ctor,您必须显式调用它。