Проблемы при создании объекта как исключения: сохранение того же конструктора родительского класса исключения - PullRequest
0 голосов
/ 02 июня 2019

Как моя первая программа на C ++, я решил создать простой TCP-сервер, основанный на предыдущих знаниях C и используя API сокетов POSIX:

Поэтому я создал следующий заголовочный файл 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 Ответ

2 голосов
/ 02 июня 2019

Вам необходимо вызвать конструктор базового класса:

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

, прежде чем тело ctor производного класса будет выполнено, все члены данных должны быть построены.Exception имеет только один ctor, который принимает строку, и вы должны вызывать ее явно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...