UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » C++
  • » `class XXXX' is inaccessible within this context

#1 2005-08-30 02:52 PM

sunny
Member
Registered: 2005-06-23
Posts: 17

Re: `class XXXX' is inaccessible within this context

Hello everybody.

I've finished reading "C++ programming language" by B. Stroustrup :-D and wanted to have some practice in "classes writing". So decided to modify my  chat server/client with writing socket classes. This idea appeares odd for newcomer both in socket programming and C++, I know, but that's so interesting...

Then, I've defined separately classes which contain data for created socket and set of operations with it(it is class with virtual functions - interface). And GenericSock is derived class.

/* gensock.h */

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

class SockError
{
		SockError();
		
	public:
	
		enum SErr { EGeneral = 0, ESend, ERecv, EConnect, EClose, ECvt };
		SErr err;
		int globerr;
		std::string errmsg;
		SockError(SErr e, int ge, std::string em): err(e), globerr(ge), errmsg(em) {};
};

class SockData
{
	protected:
	
		unsigned int socket;
		unsigned int port;
		unsigned long int ip;
		std::string addr_str;
		int socket_type;
		int protocol_family;
		int protocol_type;
		bool active;
	
	public:
		
		explicit SockData(int prot_fam, int prot_type, int sock_type, unsigned long int nip, unsigned int nport)
							:Protocol_family(prot_fam),protocol_type(prot_type),socket_type(sock_type),ip(nip),port(nport) {};
};

class SockOp_TRANSMIT
{		
	public:
	
		virtual size_t sendbuf(int s, const void *buf, size_t len, int flags) = 0;
		virtual size_t recvbuf(int s, const void *buf, size_t len, int flags) = 0;
		
		virtual ~SockOp_TRANSMIT(){}; 
};

class SockOp_GENERAL
{
	public:
	
		virtual void open() = 0;
		virtual void close() = 0;
		virtual void serve() = 0;
		
		virtual ~SockOp_GENERAL(){};
};

class SockOp_SDATAMANIP
{
	public:
	
		virtual int get_protfam() = 0;
		virtual void set_protfam(int npf) = 0;
		
		virtual int get_prottype() = 0;
		virtual void set_prottype(int npt) = 0;
		
		virtual int get_socktype() = 0;
		virtual void set_socktype(int nst) = 0;
		
		virtual unsigned sock_handle() = 0;
		
		virtual unsigned get_port() = 0;
		virtual void set_port(unsigned int nport, bool reopen = true) = 0;
		
		virtual std::string get_addr() = 0;
		virtual void set_address(unsigned long int nip, bool reopen = true) = 0;
		virtual void set_address(std::string& nip, bool reopen = true) = 0;
		
		virtual ~SockOp_SDATAMANIP(){};
};

class SockOp_EVENTPAR: public SockOp_TRANSMIT,SockOp_GENERAL 
{
	public:
		
		virtual ~SockOp_EVENTPAR(){};
};

class SockOp: public SockOp_GENERAL,SockOp_TRANSMIT,SockOp_SDATAMANIP 
{
	public:
		
		virtual ~SockOp(){};
};

class GenericSock: public SockData,SockOp
{
		GenericSock();
		GenericSock(GenericSock& );
		GenericSock& operator= (GenericSock& );

	protected:
		
		static unsigned long int str2addr(std::string& ) throw(SockError);
		static std::string addr2str(unsigned long int ) throw(SockError);

	public:
		
		explicit GenericSock(int prot_fam, int prot_type, int sock_type, unsigned long int nip, unsigned int nport)
								:SockData(prot_fam,prot_type,sock_type,nip,nport) {};
		explicit GenericSock(int prot_fam, int prot_type, int sock_type, std::string& nip, unsigned int nport)
								:SockData(prot_fam,prot_type,sock_type,GenericSock::str2addr(nip),nport) {};
		~GenericSock() { close(); }
		
		bool isactive() { return active; }
		
		virtual void close() throw(SockError);
		
		int get_protfam() { return protocol_family; }
		void set_protfam(int npf) { protocol_family = npf; }
		
		int get_prottype() { return protocol_type; }
		void set_prottype(int npt) { protocol_type = npt; }
		
		int get_socktype() { return socket_type; }
		void set_socktype(int nst) { socket_type = nst; }
		
		unsigned sock_handle() { return socket; }
		
		unsigned get_port() { return port; }
		void set_port(unsigned int nport, bool reopen = true);
		
		std::string get_addr() { return addr_str; } 
		void set_address(unsigned long int nip, bool reopen = true);
		void set_address(std::string& nip, bool reopen = true);
	
};

TCPSock is derived from GenericSock. ClientTCPSock and ServerTCPSock are "children" of TCPSock.

/* tcpsock.h */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <strings.h>
#include <string>
#include <vector>
#include "gensock.h"

class TCPSock: public GenericSock
{
		TCPSock();
		TCPSock(TCPSock& );
		TCPSock& operator= (TCPSock& );
	
	public:
		
		explicit TCPSock(unsigned long nip, unsigned nport): GenericSock(PF_INET,0,SOCK_STREAM,nip,nport) {};
		explicit TCPSock(std::string nip, unsigned nport): GenericSock(PF_INET,0,SOCK_STREAM,nip,nport) {};
		
		bool continueserving;
		
		size_t sendbuf(int s, const void *buf, size_t len, int flags);
		size_t recvbuf(int s, const void *buf, size_t len, int flags);
};

class ClientTCPSock: public TCPSock
{
		ClientTCPSock();
		ClientTCPSock(ClientTCPSock& );
		ClientTCPSock& operator= (ClientTCPSock& );
		
	public:
		
		explicit ClientTCPSock(unsigned long nip, unsigned nport): TCPSock(nip,nport) {};
		explicit ClientTCPSock(std::string nip, unsigned nport): TCPSock(nip,nport) {};
		
		void (*OnConnect) (SockOp_EVENTPAR *);
		void (*OnReceive) (SockOp_EVENTPAR *);
		void (*OnSend) (SockOp_EVENTPAR *);
		void (*OnDisconnect) (SockOp_EVENTPAR *);
		void (*OnError) (SockOp_EVENTPAR *, SockError, bool throw_exc);
		
		void open() throw(SockError);
		void serve();
		
};

class ServerTCPSock: public TCPSock
{
		ServerTCPSock();
		ServerTCPSock(ServerTCPSock& );
		ServerTCPSock& operator= (ServerTCPSock& );
		
		fd_set readset,writeset,controlset;
		int act_conn;
	
	public:
		
		explicit ServerTCPSock(unsigned long nip, unsigned nport): TCPSock(nip,nport) {};
		explicit ServerTCPSock(std::string nip, unsigned nport): TCPSock(nip,nport) {};
		
		void (*OnConnect) (SockOp_EVENTPAR *);
		void (*OnReceive) (SockOp_EVENTPAR *);
		void (*OnSend) (SockOp_EVENTPAR *);
		void (*OnDisconnect) (SockOp_EVENTPAR *);
		void (*OnError) (SockOp_EVENTPAR *, SockError, bool throw_exc);
		
		void open() throw(SockError);
		void close() throw(SockError);
		void serve();
		int num_connected() { return act_conn; }
		std::vector<SockOp_TRANSMIT*> activeconnections;
};

And here, at least, a question. I wanted to use "activeconnections" member of ServerTCPSock as list of all connected sockets (to hide all manipulations with fd_sets in class realization). I've defined it as a vector of pointers to SockOp_TRANSMIT because I wanted to use polymorphic behavior as SockOp_TRANSMIT is one of base classes for TCPSock (through GenericSock). So, for example, adding TCPSock (with proper value of "socket") to this vector, I'd have interface only to those functions of TCPSock, which provide data transmition via send(...) and recv(...) (in this case, I think that I should add there SockOp_GENERAL functionality, too), preventing usage of set_protfam(),set_prottype(), etc., which may try to close and reopen socket with new parameters(in further realization :)) but they can't do this with values of socket got with accept() call...

When I try to compile header (just to see if there is all ok)
% g++ -c tcpsock.h
compiler writes:
gensock.h:42: error: `class SockOp_TRANSMIT' is inaccessible
tcpsock.h:77: error: within this context

Why is it so?
I've probed to replace SockOp_TRANSMIT with SockOp_EVENTPAR (event parameter has to provide functionality of SockOp_TRANSMIT and SockOp_GENERAL) - all becomes ok...
And if SockOp_TRANSMIT is removed from list of base classes of SockOp, all becomes ok, too...

Sure, all that is just sketch for classes. I've planned firstly to write some blocking socket and then improve it with adding thread routines to make it possible perform requests asynchronously using those events already defined as pointers to functions. - something like in C++ Builder or Delphi. But my "courageous researches" have stopped at this stage... :(

I have too small experience in projecting and classes programming to know the reason that occures. Please, explain me...
Maybe, I'm trying to compile header too early ? :)
And is there any errors at this time you see? (Of course, except of that I've started to write all this code nonsense).
And is that right that I defined virtual destructors in all SockOp_XXXX classes and in SockOp class, too?


Thank You and sorry for such amount of text...

sunny

Offline

#2 2005-08-30 03:14 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: `class XXXX' is inaccessible within this context

Sorry, I didn't read everything you wrote, but one thing you do wrong is trying to compile headerfiles.

Headerfiles (*.h) just contain prototypes, inline stuff, that kind of things. They only give the compiler information, but don't contain real data. The real stuff is in *.cc, *.cpp or whatever source files, not in headers.

So you can't compile headerfiles. Try splitting your files into headers and source files. In the first you define the class interfaces, and in the second you give an implementation for that class. Headerfiles say what can be done, *.cc/*.cpp files tell how it is done.

Offline

  • Index
  • » C++
  • » `class XXXX' is inaccessible within this context

Board footer

Powered by FluxBB