Effective C++ Ed. 3rd: Item 34. Differenciate between inheritance of interface and inheritance of implementation

 Under public inheritance, use:
  • Pure virtual functions to specify inheritance of interface only.
  • Simple virtual functions to specify inheritance of interface plus inheritance of a default implemetation.
  • Non-virtual functions to specify inheritance of interface plus inheritance of a mandatory implementation.
Note: Instead of using simple virtual functions, we can also use pure virtual function along with their definition as shown:
class Airplane {
public:
  virtual void fly(const Airport& destination) = 0;

  ...

};

void Airplane::fly(const Airport& destination)     // an implementation of
{                                                  // a pure virtual function
  default code for flying an airplane to
  the given destination
}

class ModelA: public Airplane {
public:
  virtual void fly(const Airport& destination)
  { Airplane::fly(destination); }

  ...

};

class ModelB: public Airplane {
public:
  virtual void fly(const Airport& destination)
  { Airplane::fly(destination); }

  ...

};

class ModelC: public Airplane {
public:
  virtual void fly(const Airport& destination);

  ...

};

void ModelC::fly(const Airport& destination)
{
  ... //code for flying a ModelC airplane to the given destination
}

prev | next
Cheers and try hosting at Linode.

Effective C++ Ed. 3rd: Item 33. Avoid hiding inherited names

  • Names of functions, typedefs etc. in base class get "shadow"ed if anything with those names is present in derived class.
  • The function names get "shadow"ed irrespective of the arguments of the functions regardless of whether the functions are virtual or non-virtual.
  • Sometimes it's desirable to inherit the overloads. Use Base::functionName(); to make these visible in derived class.
  •  Say If we have Base::mf1(); and Base::mf1(int); But we only want former to be visible in derived class, the above trick won't work. Use forwarding functions as: derived::mf1(){ base::mf1() }
Note: For template classes, see item 43.
prev | next
Cheers and try hosting at Linode.

Effective C++ Ed. 3rd: Item 32. Make sure public inheritance models "is-a"

  • Where-ever object of base class can be used, derived class object can also be used but vice-versa is not true.
  • Public inheritance asserts that everything that applies to base class objects- everything! - also applies to derived class objects.
prev | next

Cheers

    Network Programming: Echo Client Server program (Iterative)

    Echo server client: The way a server program and client(program ) interacts is what their protocol (set of rules they have for interation) is!! This server client program is echo program. Once successfully connected, Client writes anything. Server reads that and send back the same text. This goes on till client disconnects or writes text beginning with "exit". This is echo protocol.

    All programs are tested in SUSE Linux Enterprise Server 10 (i586) VERSION = 10 PATCHLEVEL = 2. For how to check the distribution of linux you are running, read this.

    The server serves the client one after the other in iterative fashion.
    Echo Server program:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h> 
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    void error(const char *msg)
    {
        perror(msg);
        exit(1);
    }
    
    int main(int argc, char *argv[])
    {
         int sockfd, newsockfd, portno;
         socklen_t clilen;
         char buffer[256];
         struct sockaddr_in serv_addr, cli_addr;
         int n;
         if (argc < 2) {
             fprintf(stderr,"ERROR, no port provided\n");
             exit(1);
         }
      
    //STEP1 socket function
         sockfd = socket(AF_INET, SOCK_STREAM, 0);
         if (sockfd < 0) 
            error("ERROR opening socket");
      
    //STEP2 address structure
         bzero((char *) &serv_addr, sizeof(serv_addr));
         portno = atoi(argv[1]);
         serv_addr.sin_family = AF_INET;
         serv_addr.sin_addr.s_addr = INADDR_ANY;
         serv_addr.sin_port = htons(portno);
    
    //STEP3 bind function
         if (bind(sockfd, (struct sockaddr *) &serv_addr,
                  sizeof(serv_addr)) < 0) 
                  error("ERROR on binding"); 
    
    //STEP4 listen function
        listen(sockfd,10);
     
    //STEP5 accept and serve clients one by one in iterative fashion
     while(1){
      clilen = sizeof(cli_addr);
      newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
       if (newsockfd < 0) error("ERROR on accept");
       bzero(buffer,256);
       while(  (n=read(newsockfd,buffer,255)) > 0  ){
       if (n < 0) error("ERROR reading from socket");
       n = write(newsockfd,buffer,n);
       if (n < 0) error("ERROR writing to socket");
       bzero(buffer,256);
       }
       close(newsockfd);
     }
         close(sockfd);
         return 0; 
    }
    
    
    
    Echo Client program:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h> 
    
    void error(const char *msg)
    {
        perror(msg);
        exit(0);
    }
    
    int main(int argc, char *argv[])
    {
        int sockfd, n;
        struct sockaddr_in serv_addr;
        struct hostent *server;
    
        char buffer[256];
        if (argc < 3) {
           fprintf(stderr,"usage %s hostname port\n", argv[0]);
           exit(0);
        }
    
    //STEP1 socket function
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) 
            error("ERROR opening socket");
        server = gethostbyname(argv[1]);
        if (server == NULL) {
            fprintf(stderr,"ERROR, no such host\n");
            exit(0);
        }
     
    //STEP2 prepare address structure
        bzero((char *) &serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        bcopy((char *)server->h_addr, 
             (char *)&serv_addr.sin_addr.s_addr,
             server->h_length);
        serv_addr.sin_port = htons(atoi(argv[2]));
    
    //STEP3 connect function: request to server for connection
        if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
            error("ERROR connecting");
      
    //STEP4 read and write to server.
        while(1){
      bzero(buffer,256);
      fgets(buffer,255,stdin);//read from client stdin
      if((n=bcmp("exit",buffer,strlen(buffer))==0)){ close(sockfd); return 0; }    
      n = write(sockfd,buffer,strlen(buffer));//write to server
      if (n < 0) error("ERROR writing to socket");
      bzero(buffer,256);
      n = read(sockfd,buffer,255);//read from server and save it in array buffer
      if (n < 0) error("ERROR reading from socket");
      printf("%s\n",buffer);//write to stdout the buffer's contents
        }
        close(sockfd);
        return 0;
    }
    
    Cheers and try hosting at Linode.

    Network Programming: Day-Time Client Server program (Concurrent)

    All programs are tested in SUSE Linux Enterprise Server 10 (i586) VERSION = 10 PATCHLEVEL = 2. For how to check the distribution of linux you are running, read this.

    The server serves the client one after the other in concurrent fashion using fork().
    Server program:

    Network Programming: Date-Time Client Server program (Iterative)

    This is the first post in network programming program series.
    All programs are tested in SUSE Linux Enterprise Server 10 (i586) VERSION = 10 PATCHLEVEL = 2. For how to check the distribution of linux you are running, read this.

    The server serves the client one after the other in iterative fashion.
    Server program:

    Which distro of linux are you using?

    This is how you can check:
    Simply run the following command
    cat /etc/*-release

    This will not only tell you the linux distro you are using, but also the version number. Plus some other optional details.

    Tested on RedHat, OpenSuSe and Ubuntu server.


    Cheers and try hosting at Linode.

    Effective C++ Ed. 3rd: Item 31. Minimize compilation dependencies between files

    It is beneficial if the implementation changes in a library does not forces the clients to re-compile their code. But how would you minimize compilation dependencies? The key to this is replacement of dependencies on definitions with dependencies on declarations. There are following 2 ways:
    • Handle classes: By employing pimple idiom in classes.
    • Interface classes: By declaring abstract base class
    Besides this, libraries should be implemented as declarations and definitions in separate header files. So that clients only include header files containing declarations only.

    prev | next
    Cheers and try hosting at Linode.

    Effective C++ Ed. 3rd: Item 30. Understand the ins and outs of inlining

    • Inline functions prevent the cost of function call. However, excessive overzealous inlining leads to code bloat, resulting in addition paging, reduced cache hit rate etc.
    • Implicit inline request: when defining a function inside a class.
    • Explicit inline request: when preceding function's definition with inline keyword.

    Effective C++ Ed. 3rd: Item 29. Strive for exception-safe code

    When an exception is thrown, a exception-safe fuction:
    • Leak no resources
    • do not make data structures corrupt.
    Exception-safe functions should offer one of three guarantees:
    • the basic guarantee
    • the strong guarantee
    • the nothrow guarantee

    Effective C++ Ed. 3rd: Item 28. Avoid returning "handles" to object internals.

    While returning internal handles from a member function, consider
    • returning const object. This results in read-only access of the returned parameter.
    The problem with dangling references will still remains. So it's better to avoid returning reference, pointer or iterators from a function. This would minimize dangling handles and also might provide better encapsulation in case of member functions.

    prev | next
    Cheers and try hosting at Linode.