Sunday, July 3, 2022

C++ API Design Best Practices - Hiding Data Members and Implementation

HIDE IMPLEMENTATION DETAILS

                                                                        Image source 

Declaration 

  • A declaration simply introduces a name, and its type, to the compiler without allocating any memory for it.

Definition 

  • Provides details of a type’s structure or allocates memory in the case of variables.
  • If provide a definition for a method in the header -it exposes how the method has been implemented and directly inline code onto client's program, this is bad practice 
  • Therefore limit API headers to only provide declarations.

Physical hiding

  • Physical hiding means storing internal details in a separate file (.cpp) from the public interface (.h).

Logical Hiding

  • Logical hiding means using the C++ language features of protected and private to restrict access to internal details. 
  • C++ this is implemented using the following access control keywords for classes and structs

Encapsulation 

  • Encapsulation is the process of separating the public interface of an API from its underlying implementation.

Hide Member Variables

  • Data members of a class should always be declared private, never public or protected.
  • Use using getter/setter routines, rather than exposing member variables directly,
  • Also can make any variable read-only by not providing a setter method.
  • Synchronization You may release the first version of your API and then later find that you need to make it thread-safe. The standard way to do this is to add mutex locking whenever a value is accessed. This would only be possible if you have wrapped access to the data values in getter/setter methods.
  • In the below examples 1st one, the class exposes everything to the client's program, therefore 2nd  example should be preferred 

Hide Implementation Methods

  • In addition to hiding all member variables, you should also hide all methods that do not need to be public.
  • It should be clear that hiding the internal details of your API will make for more maintainable and evolvable software.
  • Use the Pimpl idiom in your APIs so that all implementation details can be completely hidden from your public header files.
  • When providing a public method (public getter method) that returns access to a private member variable, never return non-const pointers or references to private data members. if do client can modify the object's internal state it breaks encapsulation.
  • Example method -> int GetMemeberId() const; method declared as const, this means it won't let the client change the state of class
  • Prefer declaring private functionality as static functions within the .cpp file rather than exposing them in public headers as private methods. (Using the Pimpl idiom is even better though.)

 Hide Implementation Classes

  • Hide any actual classes that are purely an implementation detail.
  • Consider that not all classes should be made public.
  • Suppose clients of the API never need to access Class B, and it’s purely required for the API’s implementation. This Class B could therefore be made private, by nesting it in Class B within a private section of Class A. so that the client can access Class A public methods and public member variables but not Class B.

                            
                               ClassA
                               {
                                public: 
                                    ClassA();
                                    void methodA();
                                private:
                                    ClassB
                                    {
                                    public: 
                                        ClassB();
                                        void methodB();   
                                    private:
                                        int memberB = 0;
                                    }
                                }

 





No comments:

Post a Comment

LeetCode C++ Cheat Sheet June

🎯 Core Patterns & Representative Questions 1. Arrays & Hashing Two Sum – hash map → O(n) Contains Duplicate , Product of A...