0

Suppose i have a socket class:

class Socket{
public:
    ... Some Code ...
    Socket(int type){
         isServer = type;
        //some code
    }
    virtual void Send(string s);
    virtual void Send(string s, int clientID);
    ... Some Code ...
private:
    int isServer;
};

This is to be used both as a server and client.

Now I need to have 2 Derived classes:

class ClientSocket : public Socket{
public:
    ... Some Code ...
};

class ServerSocket : public Socket{
public:
    ... Some Code ...
};

What I want is that ClientSocket will only have access to Send(string) and server socket will only have access to Send(string, int)

I checked some other answer:

And that has a good idea of not using inheritance at all rather just encapsulate(Have a socket instance in server). But I want to know whether this can be done using Inheritance.

Jaysmito Mukherjee
  • 1,467
  • 2
  • 10
  • 29
  • "`ClientSocket` will only have access to..." sounds like a compile time property, but virtual function calls are dispatched at run time. – Evg May 26 '21 at 05:05
  • 1
    To me it sounds like these `Send` functions shouldn't be part of the base `Socket` class, but instead of the inherited classes instead. – Some programmer dude May 26 '21 at 05:07
  • @Evg not compile time if you go for inheritance i guess. and for virtual functions i must do it as the code is implemented in different place to make it platform independent – Jaysmito Mukherjee May 26 '21 at 05:07
  • Then what is "only have access to..."? What should happen if you try to get access, but there should be no access? Compilation error, exception, termination, ...? – Evg May 26 '21 at 05:09
  • @Someprogrammerdude Yeah but i want to Have a raw socket version having all functions of a socket at same place as i am trying to be platfrom independent it will be very difficult to have Seperate implementations for diff classes – Jaysmito Mukherjee May 26 '21 at 05:09
  • @Evg As of now I implemented kind of a runtime error. But i dont exactly what would be better – Jaysmito Mukherjee May 26 '21 at 05:11
  • If you have a socket and don't know whether or not it's a server or client, how do you know which send to use? If you can't know, then inheritance doesn't make sense. You don't have a valid is-a relationship. – user4581301 May 26 '21 at 05:12
  • 2
    Design-wise that doesn't make much sense to me. Server and client sockets, at least for TCP, have very different behavior. A server socket should not really have any "send" or "receive" functions at all, only "listen" and "accept" type operations. The "accept" operation returns a client socket object, which can send and receive generic data. Then you can have a container-like class wrapping multiple client socket objects, and it could have a function to send to all sockets, or only one specific socket. – Some programmer dude May 26 '21 at 05:16
  • @user4581301 i do know it i have a isServer – Jaysmito Mukherjee May 26 '21 at 05:17
  • @Someprogrammerdude Here i did this trying to abstract the entire socket thing (like this will be same for windows linux mac) and Here i have an Accept method which returns a int (the ClientID) and Design wise i think i should make the Send(string, int) static as it is not related to the server instance at all – Jaysmito Mukherjee May 26 '21 at 05:25
  • 1
    Where I'm going is if you have to call `isServer` or otherwise know you have a `ServerSocket`, then you gain next to nothing from polymorphism, so don't do it. The program will be more efficient without it. Polymporphism is at it's best when you don't need to know the exact derived type. Right now You're fighting against the [Liskov Substituion Principle](https://stackoverflow.com/questions/56860/what-is-an-example-of-the-liskov-substitution-principle), and that's going to bring pain that is only just beginning. – user4581301 May 26 '21 at 05:28
  • If you need to keep track of what kind of derived class your polymorphic pointer points to, your design is most likely bad. There is no good way to solve that issue. I would recommend going back to the drawing board and making some changes in your design. – super May 26 '21 at 05:31
  • @super I guess i will. I think i will seperate out ClientSocket and ServerSocket – Jaysmito Mukherjee May 26 '21 at 05:39
  • Historical: I did almost exactly this about 10 years ago back. I regretted it thoroughly about a year later once I'd used it in a few projects and tried porting it to a few more OSes. I've been trying to kill it off for at least 8 years now, but it just won't smurfing die. I keep having to support stuff based on it. "Hey man, when are you fixing corelib::net?" "It's unfixable. Stop using it." "Ha ha ha ha ha. Seriously man, When are you fixing corelib?" It LOOKS like a good idea until you really start using it. – user4581301 May 26 '21 at 05:55

1 Answers1

1

There is not absoulte way to doing such thing.

But here my idea:

create two class(like interface):

first class is server socket sender:

Class ServerSocketSender {
  public:
    virtual void Send(string s, int clientID);
}

second class is client socket sender:

Class ClientSocketSender {
  public:
    virtual void Send(string s);
}

due to interface segregation principle i recommend you to do such thing it is not wise choice to combine two send method in one class and enable desire method in desire class.

another trick that i saw many times but i dont know exactly if it's work in your case or not is something called SFINAE. with this trick i think you can achieve same thing but due to complexity i not recommend this approach.

N0ll_Boy
  • 500
  • 3
  • 6
  • I already told i do not want to implement any Different class as those Send methods use some OS Native API thus it is very confusing to have different classes for that as it will increase code size and make it difficult to maintain – Jaysmito Mukherjee May 26 '21 at 05:16
  • 2
    if you dont want use extra class i recommend you to put send methods in inherited class not base class because they have different signature and purpose so it is not correct in term of OOP. – N0ll_Boy May 26 '21 at 05:18
  • Again it is not practical i may use the Socket class directly also – Jaysmito Mukherjee May 26 '21 at 05:19
  • use SFINAE [link](https://stackoverflow.com/questions/42514100/crtp-enable-methods-in-base-class-based-on-derived-class-contents) – N0ll_Boy May 26 '21 at 05:22
  • SFINAE is a compile time mechanism, but virtual calls is a run time one. – Evg May 26 '21 at 05:22
  • @Evg I don't think we need to use virtual functions. CRTP allows inheritance without virtual functions and all he wanted was inheritance. Or did I misunderstand the original question? – Jerry Jeremiah May 26 '21 at 06:01
  • @JerryJeremiah I somewhat agree with you. But from the question it is not clear whether CRTP is a good solution - too little detail about the problem and requirements. – Evg May 26 '21 at 06:30