-1

I have main code that looks like this:

#include "ClientSocket.h"
#include "SocketException.h"
#include <iostream>
#include <string>

int main ( int argc, char argv[] )
{
    std::cout << "" << std::endl;
    try
    {   
        ClientSocket client_socket ( "localhost", 30000 );
        std::string reply;

        try
        {
            client_socket << "Test message.";
            client_socket >> reply;
        }
        catch ( SocketException& ) {}

        std::cout << "We received this response from the server:\n\"" << reply << "\"\n";;
    }
    catch ( SocketException& e )
    {
        std::cout << "Exception was caught:" << e.description() << "\n";
    }

    return 0;
}

A header file that looks like this:

// Definition of the ClientSocket class

#include "ClientSocket.cpp"
#include "Socket.h"
#ifndef _CLIENTSOCKET_H
#define _CLIENTSOCKET_H

class ClientSocket : private Socket
{
    public:
        ClientSocket ( std::string host, int port );
        virtual ~ClientSocket(){};
        const ClientSocket& operator << ( const std::string& ) const;
        const ClientSocket& operator >> ( std::string& ) const;
};

#endif

And an implementation file that looks like this:

// Implementation of the ClientSocket class

#include "Socket.h"
#include "SocketException.h"

ClientSocket::ClientSocket ( std::string host, int port )
{
    if ( ! Socket::create() )
    {
        throw SocketException ( "Could not create client socket." );
    }

    if ( ! Socket::connect ( host, port ) )
    {
        throw SocketException ( "Could not bind to port." );
    }
}

const ClientSocket& ClientSocket::operator << ( const std::string& s ) const
{
    if ( ! Socket::send ( s ) )
    {
        throw SocketException ( "Could not write to socket." );
    }

    return *this;
}

const ClientSocket& ClientSocket::operator >> ( std::string& s ) const
{
    if ( ! Socket::recv ( s ) )
    {
        throw SocketException ( "Could not read from socket." );
    }

    return *this;
}

I've found that compiling these files causes a raft of compilation errors in the implementation file specifically, no matter what combination of includes and guards I use.

In file included from ClientSocket.h:3:0,
                 from simple_client_main.cpp:1:
ClientSocket.cpp:6:1: error: 'ClientSocket' does not name a type
 ClientSocket::ClientSocket ( std::string host, int port )
 ^
ClientSocket.cpp:19:7: error: 'ClientSocket' does not name a type
 const ClientSocket& ClientSocket::operator << ( const std::string& s ) const
       ^
ClientSocket.cpp:29:7: error: 'ClientSocket' does not name a type
 const ClientSocket& ClientSocket::operator >> ( std::string& s ) const
       ^

The ones posted are what seemed to make the most sense. I've tried including the header file in the implementation file, which does nothing. I've tried removing the include from the header file and including the header in the implementation file, but this replaces the 'does not name a type' errors with undefined reference errors. Is there something in the code preventing compilation?

  • 2
    Never include a cpp file. –  May 17 '17 at 22:44
  • 2
    And never use header guards in this form `_CLIENTSOCKET_H` - simply use `CLIENTSOCKET_H`. And put the header guards around _everything_ in the header file. –  May 17 '17 at 22:45
  • 1
    Names starting with underscore followed by an upper-case letter are reserved for the implementation. *Never* use such names in your own code (not even for header guards). – Jesper Juhl May 17 '17 at 22:47
  • 1
    `#include "ClientSocket.cpp"` is wrong!! – πάντα ῥεῖ May 17 '17 at 22:51
  • [And knowing is half the battle.](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) Yo Joe. – user4581301 May 17 '17 at 22:53

2 Answers2

1

A header file that looks like this:

// Definition of the ClientSocket class

#include "ClientSocket.cpp" <== this definitely looks wrong.

Normally you do not include cpp files. It's the other way around, your ClientSocket.cpp should include your ClientSocket.h:

// Implementation of the ClientSocket class
#include "ClientSocket.h"
#include "SocketException.h"

ClientSocket::ClientSocket(std::string host, int port)
{
   ...

Header guard _CLIENTSOCKET_H in your ClientSocket.h should come before you include Socket.h, also do not use names that start with one or two underscores (they are reserved identifiers):

#ifndef CLIENTSOCKET_H
#define CLIENTSOCKET_H

#include "Socket.h"

class ClientSocket : private Socket
{
    ...
};

#endif /* CLIENTSOCKET_H */

Your ClientSocket.h references std::string, perhaps it's included from Socket.h. If not, you should include it from ClientSocket.h

Pavel P
  • 15,789
  • 11
  • 79
  • 128
  • I might not have been clear, but including the .h in the .cpp simple gives me undefined reference errors when I compile the main code. – user3564783 May 17 '17 at 23:19
  • @user3564783 Can you update your question with this error message? – Pavel P May 17 '17 at 23:33
  • @user3564783 you mean undefined reference from linker? You have to compile your ClientSocket.cpp separately as well and link resulting ClientSocket.o – Pavel P May 17 '17 at 23:44
  • Yes, linker errors are what I mean. Do I need to compile the header files and the implementation files at once? – user3564783 May 17 '17 at 23:54
  • @user3564783 No, you compile only .cpp files, headers (.h) are usually included by .cpp files. – Pavel P May 18 '17 at 00:04
0

You should not try to include ClientSocket.cpp from what I believe is ClientSocket.h. Note that 'include' is just a test substitution, and in this case you are effectively substituting the contents of ClientSocket.cpp (including the method definitions of the yet undeclared ClientSocket class) before the definition of the class itself.

Also, ClientSocket.cpp does not include ClientSocket.h, and therefore either does not have access to ClientSocket class definition at all, or has it via other headers, the latter case being highly discouraged.

iehrlich
  • 3,572
  • 4
  • 34
  • 43