2015-07-05 73 views
-1

我有一些工作代碼,但錯誤處理現在相當粗糙 - 它通常發送錯誤字符串到標準錯誤並退出。所以我希望它拋出一個異常,並允許用戶處理它,因爲他們選擇一個典型的處理程序。爲什麼添加try塊導致編譯器錯誤

但是,在代碼中添加了一個try catch塊,它給了我一個我根本不理解的編譯器錯誤。

我的代碼如下所示:

// ------------------------------------------------------------------------- 
sockets::TCPSocket::TCPSocket(const char* address, const int port) 
{ 
    this->address = address; 
    this->port  = port; 
    this->bufferSize = sockets::TCPSocket::DEF_BUFFER; 
    sockets::TCPSocket::init(); 
} 

// ------------------------------------------------------------------------- 
sockets::TCPSocket::~TCPSocket() 
{ 
    freeaddrinfo(this->addressInfoList); 
    close(this->filedes); 
} 

// ------------------------------------------------------------------------- 
void sockets::TCPSocket::init() 
{ 
    memset(&(this->addressInfo), 0, sizeof this->addressInfo); 

    addressInfo.ai_family = AF_UNSPEC;  // Either IPv4 or IPv6 
    addressInfo.ai_socktype = SOCK_STREAM; // Uses TCP 
    addressInfo.ai_flags = AI_PASSIVE;  // Accept any IP 

    // get the address info 
    int status = getaddrinfo(
     this->address, 
     std::to_string(this->port).c_str(), 
     &(this->addressInfo), 
     &(this->addressInfoList) 
    ); 

    if (status != 0) // any error- segfault if addressInfoList not allocated 
    { 
     throw GetAddrinfoException(); 
    } 

    // create socket 
    this->filedes = socket(
     this->addressInfoList->ai_family, 
     this->addressInfoList->ai_socktype, 
     this->addressInfoList->ai_protocol 
    ); 

    if (this->filedes == -1) 
    { 
     std::cerr << "Create socket error: " << strerror(errno) << std::endl; 
     exit(EXIT_FAILURE); 
    } 
} 

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

正如你看到的,我呼籲從我的構造函數(私人)init()函數。我在我的init()函數中拋出GetAddrinfoException。如果我在構造函數的try catch中調用init(),它可以正常工作。但是,當我把它從我的主 - 期待棧放鬆 - 我得到一個編譯錯誤..這樣的:

int main() 
    { 
     using namespace std; 

     // Test as client 
     const char* TEST_ADDR = "www.google.com"; 
     try 
     { 
      sockets::TCPSocket socket = sockets::TCPSocket(TEST_ADDR, 80); 
     } 
     catch (sockets::GetAddrinfoException e) { /* do something */ } 

    return 0; 
} 

編譯器錯誤每個的TCPSocket的成員函數列表,並給出了這樣的消息:

TCPSocket/test.cpp: In function ‘int main()’: 
TCPSocket/test.cpp:22:12: error: request for member ‘doConnect’ in ‘socket’, which is of non-class type ‘int(int, int, int) throw()’ 
    socket.doConnect(); 
      ^
TCPSocket/test.cpp:23:12: error: request for member ‘doSend’ in ‘socket’, which is of non-class type ‘int(int, int, int) throw()’ 
    socket.doSend("GET/HTTP/1.1\r\nHost: www.redway-soft.com\r\n\r\n"); 
      ^
TCPSocket/test.cpp:24:20: error: request for member ‘doRecv’ in ‘socket’, which is of non-class type ‘int(int, int, int) throw()’ 
    cout << socket.doRecv() << endl; 
        ^
TCPSocket/test.cpp:34:12: error: request for member ‘restart’ in ‘socket’, which is of non-class type ‘int(int, int, int) throw()’ 
    socket.restart(); 
      ^
TCPSocket/test.cpp:35:30: error: request for member ‘doListen’ in ‘socket’, which is of non-class type ‘int(int, int, int) throw()’ 
    string received = socket.doListen(); 
          ^

儘管搜索了多個教程和指南,但我找不到任何此問題的原因。任何幫助將非常感激。

編輯:

類定義是這樣的:

#ifndef __TCPSOCKET_HPP__ 
#define __TCPSOCKET_HPP__ 

#include <cstring> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <unistd.h> 
#include <string> 
#include <vector> 
#include <iostream> 
#include <cerrno> 
#include <exception> 


namespace sockets 
{ 

    class GetAddrinfoException: std::exception 
    { 
     public: 
      virtual const char* what() const throw() 
      { 
       return "getAddressinfo() failure"; 
      } 
    }; 



    /** 
    * @class TCPSocket, creates a HTTP/TCP Socket. TCPSocket is designed with the idea 
    * that it should usually be instantiated in its own thread for most use cases. 
    * @param const char* address, e.g. www.google.com 
    * @param int port, which port defaults 80 
    */ 
    class TCPSocket 
    { 
     private: 

      /** 
      * Instance vars 
      */ 
      struct addrinfo addressInfo; 
      struct addrinfo* addressInfoList; 
      int    filedes; 
      const char*  address; 
      int    port; 
      int    bufferSize; 

      /** 
      * @function init, allows socket to be re-assigned a new address and port 
      */ 
      void init(); 

     public: 

      /** 
      * pulbic class vars 
      */ 
      static const int DEF_BUFFER = 2000; 
      static const int DEF_PORT  = 5556; 
      static const int DEF_TIMEOUT = 200000; 
      static const int DEF_NUMTRIES = 5; 

      /** 
      * @constructor 
      * @param address, to connect to default is NULL siffnifying server socket 
      * @param port, port to connect/listen on 
      */ 
      TCPSocket(const char* address = NULL, const int port = DEF_PORT); 
      /** 
      * @destructor 
      */ 
      ~TCPSocket(); 

      /** 
      * public getters 
      */ 
      inline const char*   getAddress()   {return this->address;} 
      inline const int&    getPort()   {return this->port;} 
      inline const struct addrinfo& getAddressInfo()  {return this->addressInfo;} 
      inline const int&    getFiledes()   {return this->filedes;} 
      inline const struct addrinfo* getAddressInfoList() {return this->addressInfoList;} 

      /** 
      * @function setBuffer, set bufferSize to custom size 
      * @param buffer, the size to set the read in buffer 
      */ 
      inline void setBuffer(int buffer) {this->bufferSize = buffer;} 

      /** 
      * @function restart, cleans up and then re-initialises the socket with new params 
      * @param address, to connect to 
      * @param port, port to connect 
      */ 
      void restart(const char* address = NULL, const int port = DEF_PORT); 

      /** 
      * @function doConnect, connect to target address 
      */ 
      void doConnect(); 

      /** 
      * @function doSend - sends specific message, 
      * @param message e.g. "GET/HTTP/1.1\r\nHost: www.google.com\r\n\r\n" 
      * would send a simple get request, or a html string could be sent back 
      * in the case of send from a server socket which is responding to a 
      * request. 
      */ 
      void doSend(const char* message); 

      /** 
      * @function doRecv, gets return data from server 
      * @param timeout, length of time to wait (micros) for data def = 100 000 
      * @param numtries, number of attempts at reading data if none recv 
      * @return message that has been received 
      */ 
      std::string doRecv(int timeout = DEF_TIMEOUT, int numtries = DEF_NUMTRIES); 

      /** 
      * @function doListen, listens at given port and accepts a connection 
      * note that this function is blocking and so any implementation should 
      * probably normally be on its own thread/process, a server class should 
      * be in charge of managing individual threads and sockets. 
      */ 
      std::string doListen(); 


      /** 
      * @function doClose, closes the filedescripter. 
      */ 
      void doClose(); 
    }; 
} 

#endif 
+0

什麼是_'catch(GetAddrinfoException e){/ *做些什麼* /}'_實際上? –

+0

它看起來像錯誤的起源是在你的類定義的'sockets :: TCPSocket'中的某處。 – ikrabbe

+0

我將添加類頭文件。你是什​​麼意思πάνταῥεῖ?我猜你知道什麼try {} catch(){}塊是... –

回答

1

我的水晶球在您使用socket超越catch塊,但它的範圍,直到的結尾告訴我嘗試阻止。在try塊中使用socket做你需要的。

它沒有聲明socket沒有聲明的原因是因爲它是一個函數,例如Linux的this one或Windows的this one。在你的try塊內部,局部變量會遮蔽該函數。

+0

我認爲你已經擊中了頭部,很有猜測!我多麼愚蠢!謝謝。 –

相關問題