From: Catherine Heathcote on
This is probably a really simple question and chances are I am missing
something very obvious, but I havn't done any coding since uni 6 years
ago!

I have a few files: main.cpp sock.h/.cpp client.h/.cpp
I have tried compiling them with "g++ -c <insert cpp file>" then sticking
them together with "g++ -o runme sock.o client.o main.o"

Thing is I get errors about undefined references to some members. Now the
client class is inhereted from the sock class, but thats as complicated
as it gets.

"g++ sock.cpp client.cpp main.cpp" doesnt work either, what am I doing
wrong? Code follows:

// main.cpp
#include <iostream>
#include "client.h"
using namespace std;

int main(int argc, char* argv)
{
cout<<"Program entry point\n";
client testy;

return 0;
}

// sock.h
#ifndef _SOCK_H_
#define _SOCK_H_

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string>
#include <arpa/inet.h>

class sock
{
private:
int m_sock;
sockaddr_in m_addr;
public:
sock();
~sock();

// Server initialisation
bool create();
bool bind(const int port);
bool listen() const;
bool accept(sock&) const;

// Client initialisation
bool connecct(const std::string host, const int port);

// Data transmision
bool send(const std::string) const;
int recv(std::string&) const;

void set_non_blocking(const bool);
bool is_valid() const {return m_sock != -1;}
};

#endif

// sock.cpp
#include "sock.h"
#include <string>

sock::sock() : m_sock(-1)
{
memset(&m_addr, 0, sizeof(m_addr));
}

sock::~sock()
{
if(is_valid())
::close(m_sock);
}

bool sock::create()
{
m_sock = socket(AF_INET, SOCK_STREAM, 0);
if(!is_valid())
return false;

return true;
}

// client.h
#ifndef _CLIENT_H_
#define _CLIENT_H_

#include "sock.h"

class client : private sock
{
private:
public:
client(int port);
client() {};
~client();

const client& operator <<(const std::string&) const;
const client& operator >>(std::string&) const;

void accept(sock&);
};

#endif

// client.cpp
#include <iostream>
#include "client.h"

client::client(int port)
{
if(!sock::create())
std::cout<<"Could not create server socket\n";
if(!sock::bind(port))
std::cout<<"Could not bind to port "<<port<<"\n";
if(!sock::listen())
std::cout<<"Could not bind to socket\n";
}

client::~client()
{

}

const client& client::operator <<(const std::string& s) const
{
if(!sock::send(s))
std::cout<<"Could not write to socket\n";

return *this;
}

const client& client::operator >>(std::string& s) const
{
if(!sock::recv(s))
std::cout<<"Could not read from socket\n";

return *this;
}

void client::accept(sock& sckt)
{
if(!sock::accept(sckt))
std::cout<<"Could not accept socket\n";
}
From: Ben Bacarisse on
Catherine Heathcote <catherine.heathcote(a)ntlworl.com> writes:

> I have a few files: main.cpp sock.h/.cpp client.h/.cpp
> I have tried compiling them with "g++ -c <insert cpp file>" then sticking
> them together with "g++ -o runme sock.o client.o main.o"
>
> Thing is I get errors about undefined references to some members. Now the
> client class is inhereted from the sock class, but thats as complicated
> as it gets.

You get errors about sock::accept (and others) not being defined
because they are not defined! I know this sounds too obvious, but I
don't know where your confusion comes from.

Your sock.cpp defines member functions sock::sock, sock::~sock and
sock::create but that is all. The others (like sock::accept) need to
be written for the program to link correctly.

[I'll note in passing, that:

> class sock
> {
> private:
....
> public:
....
> bool accept(sock&) const;
....
> };

looks a little odd. class client is derived from class sock and
client::accept calls sock::accept, but it probably does not need to be
passed a sock reference. It is not obviously wrong, it just looks a
little confused.]

--
Ben.
From: Catherine Heathcote on
On Mon, 07 Jan 2008 14:17:53 +0000, Ben Bacarisse wrote:

> Catherine Heathcote <catherine.heathcote(a)ntlworl.com> writes:
>
>> I have a few files: main.cpp sock.h/.cpp client.h/.cpp I have tried
>> compiling them with "g++ -c <insert cpp file>" then sticking them
>> together with "g++ -o runme sock.o client.o main.o"
>>
>> Thing is I get errors about undefined references to some members. Now
>> the client class is inhereted from the sock class, but thats as
>> complicated as it gets.
>
> You get errors about sock::accept (and others) not being defined because
> they are not defined! I know this sounds too obvious, but I don't know
> where your confusion comes from.
>
> Your sock.cpp defines member functions sock::sock, sock::~sock and
> sock::create but that is all. The others (like sock::accept) need to be
> written for the program to link correctly.
>
> [I'll note in passing, that:
>
>> class sock
>> {
>> private:
> ...
>> public:
> ...
>> bool accept(sock&) const;
> ...
>> };
>
> looks a little odd. class client is derived from class sock and
> client::accept calls sock::accept, but it probably does not need to be
> passed a sock reference. It is not obviously wrong, it just looks a
> little confused.]

Yea that was a little embarrasing! I somehow managed to replace the file
with the backup. Sorry :$
From: Rui Maciel on
Catherine Heathcote wrote:

> "g++ sock.cpp client.cpp main.cpp" doesnt work either, what am I doing
> wrong? Code follows:

Compilers usually only compile one source file at a time. GCC's compilers
like gcc and g++ certainly work that way. When you need to build a project
which is made up by more than one file, you need to compile each source
file individually and then link them accordingly.

In order to simplify that process, quite a few automated build tools have
been written. One which, I believe, is the main tool to do that sort of job
is the make program.

With make, you simply need to define a build script (the Makefile)
specifying each build stage and the stage's precedences. When you need to
build your program you simply run the make program and it takes care of
everything. So basically, instead of compiling everything by hand, you just
specify the build precedences and then make takes care of everything else.

So, to sum things up, look for a make tutorial.


Rui Maciel
From: Bart van Ingen Schenau on
Rui Maciel wrote:

> Catherine Heathcote wrote:
>
>> "g++ sock.cpp client.cpp main.cpp" doesnt work either, what am I
>> doing wrong? Code follows:
>
> Compilers usually only compile one source file at a time. GCC's
> compilers like gcc and g++ certainly work that way. When you need to
> build a project which is made up by more than one file, you need to
> compile each source file individually and then link them accordingly.

Most compilers, including the GCC ones, will do that automatically if
you specify multiple source files to build.
Each file specified on the command line gets compiled, and the resulting
object code of all the files is linked into an executable.

For simple projects, that happen to consist of more than one source
file, there is no need to use external build tools, such as 'make'.
Once you have more than a handful of files in your project, a tool
like 'make' will be worth the effort of learning how to use it.

> Rui Maciel

Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://c-faq.com/
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
 | 
Pages: 1
Prev: delete pointer
Next: Linux and C