'OOP sobreencapsulation

Lately I've been learning something about blockchain and I decided to try to make one in c++, without libraries that were made specifically for that, just with the basic ones.

I don't know if it was the best option but I decided to start with sockets and implement something similar to Python's "socket" library.

When a socket receives a connection, the Accept function returns a descriptor file of a new socket from which we can read and write data. But, that socket cannot receive other connections, and this is where the question comes from.

If I make a class to manage each socket like this:

// sock.h
// example code (there may be errors)

#include <sys/socket.h>
#include <netinet/in.h>

typedef unsigned int sock_t;

class Sock
{
    public:
        Sock();
        Sock(sock_t n);
        ~Sock();
        sock_t Get();
        int Bind();
        int Listen();
        sock_t Accept();
        int Connect();
        int Close();
    private:
        sock_t fd;
        struct sockaddr_in address;
};

And I use it like this to receive a connection:

//main.cpp

#include "sock.h"

int main()
{
    Sock s;
    s.Bind("0.0.0.0", 1234);
    s.Listen(64);
    Sock t(s.Accept());
    t.Bind();                    //  <-- error (should i encapsulate or handle the error?)
}

By returning the Accept function a socket_t type and creating another Sock object with it, the Accept, Bind or Connect function could be called. And that is not possible, it will give an error.

This is where different solutions appear:

  1. Handle error.
  2. Create a new type of unsigned int, different from socket_t, and return it from Accept. So the Accept, Bind or Connect functions only accept socket_t (or something similar).
  3. Create 2 different classes. One for the Read, Send, and Close functions; and one for the SetSockOpt, Bind, Listen, Accept and Connect functions. So the second class inherits from the first.

I don't know which of the three options is the most correct (or if there are more options). Maybe it's a stupid question, but I don't just want to reduce the problem to this specific example since, remembering previous projects, it is a question that has arisen at other times. From my intuition I think that the best option is the last one, but I don't know if I'm right.

How can I know when something is overencapsulated? Is it good to restrict the access of one or several functions to the rest of the program? Or is it convenient to form the entire program with fully encapsulated modules?

I guess this all depends on a lot of things.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source