1

inheritance sequence: BasicWinsockSocket <- WinsockTCPSocket <- WinsockTCPClient

WinsockTCPClient calls WinsockTCPSocket's constructor, which in turn calls BasicWinsockSocket's constructor, which is not empty. Despite this, the compiler tries to call BasicWinsockSocket::BasicWinsockSocket() , which doesn't exist:

WinsockTCPClient.h:

class WinsockTCPClient
    : public virtual ITCPClient,
      public virtual WinsockTCPSocket
{
public:
    WinsockTCPClient(const std::string& ip, uint16_t port, bool auto_connect = true);
    virtual ~WinsockTCPClient() {}
};

WinsockTCPClient.cpp:

WinsockTCPClient::WinsockTCPClient(
    const std::string& ip,
    uint16_t port,
    bool auto_connect)
    : WinsockTCPSocket(ip, port)
{
    if( auto_connect )
        Connect();
}

WinsockTCPSocket.h:

class WinsockTCPSocket
    : public virtual BasicWinsockSocket
{
public:
    WinsockTCPSocket()
        : BasicWinsockSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
    {}
    WinsockTCPSocket(const std::string& ip, uint16_t port)
        : BasicWinsockSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, ip, port)
    {}
    virtual ~WinsockTCPSocket() {}
};

BasicWinsockSocket.h:

class BasicWinsockSocket
    : public virtual ISocket
{
public:

    BasicWinsockSocket(int address_family,
                       int type,
                       int protocol);
    BasicWinsockSocket(int address_family,
                       int type,
                       int protocol,
                       const std::string& ip,
                       uint16_t port);
    BasicWinsockSocket(SOCKET socket, struct sockaddr_in addr)
        : m_socket(socket), m_addr(addr)
    {}
    virtual ~BasicWinsockSocket();

protected:

    SOCKET m_socket;

    SockAddrIn m_addr;

    int m_lastError;
};

BasicWinsockSocket.cpp:

BasicWinsockSocket::BasicWinsockSocket(
    int address_family,
    int type,
    int protocol)
    : m_socket( socket(address_family, type, protocol) )
{
    if ( INVALID_SOCKET == m_socket )
        m_lastError = WSAGetLastError();
}

BasicWinsockSocket::BasicWinsockSocket(
    int address_family,
    int type,
    int protocol,
    const std::string& ip,
    uint16_t port)
    : m_socket( socket(address_family, type, protocol) ),
      m_addr(ip, port)
{
    if ( INVALID_SOCKET == m_socket )
        m_lastError = WSAGetLastError();
}

BasicWinsockSocket::~BasicWinsockSocket()
{
    this->Close();
}

Error:

||=== Build: Debug in x (compiler: GNU GCC Compiler) ===|
src\networking\WinsockTCPClient.cpp||In constructor 'networking::WinsockTCPClient::WinsockTCPClient(const string&, uint16_t, bool)':|
src\networking\WinsockTCPClient.cpp|14|error: no matching function for call to 'networking::BasicWinsockSocket::BasicWinsockSocket()'|
src\networking\WinsockTCPClient.cpp|14|note: candidates are:|
include\networking\BasicWinsockSocket.h|28|note: networking::BasicWinsockSocket::BasicWinsockSocket(SOCKET, sockaddr_in)|
include\networking\BasicWinsockSocket.h|28|note:   candidate expects 2 arguments, 0 provided|
include\networking\BasicWinsockSocket.h|23|note: networking::BasicWinsockSocket::BasicWinsockSocket(int, int, int, const string&, uint16_t)|
include\networking\BasicWinsockSocket.h|23|note:   candidate expects 5 arguments, 0 provided|
include\networking\BasicWinsockSocket.h|20|note: networking::BasicWinsockSocket::BasicWinsockSocket(int, int, int)|
include\networking\BasicWinsockSocket.h|20|note:   candidate expects 3 arguments, 0 provided|
include\networking\BasicWinsockSocket.h|15|note: networking::BasicWinsockSocket::BasicWinsockSocket(const networking::BasicWinsockSocket&)|
include\networking\BasicWinsockSocket.h|15|note:   candidate expects 1 argument, 0 provided|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
W2a
  • 736
  • 2
  • 9
  • 23
  • 1
    I think you need to re-read about the semantics of virtual inheritance. – ildjarn Feb 18 '17 at 13:13
  • http://stackoverflow.com/questions/2126522/c-virtual-inheritance – M.M Feb 18 '17 at 13:16
  • tl;dr when there is a virtual base, the most-derived class has to provide ctor-initializer, otherwise there would be clashes of initializer – M.M Feb 18 '17 at 13:17

0 Answers0