Search code examples
c++privateencapsulationpublicdata-members

Encapsulating data so the setter is private and getter is public


I was wondering how it is best to create a data entity in C++, where the "setter" is private and "getter" is public. i.e the creator of the entity should be able to set the data, but the user/consumer/client is only able to get the data.

Lets consider the entity EntityX:

class EntityX
{
  public:
    EntityX(int x, int y) : x(x), y(y)
    {}
    int GetX() const {return x;}
    int GetY() const {return y;}
  private:
    int x,y; // Effective C++ third edition, Item 22: Declare data members private
}

And a class method which creates the entity and returns it to the client:

const shared_ptr<EntityX> classz::GetEntityX()
{
  shared_ptr<EntityX> entity(new EntityX(1,2));

  return entity;
}

This in my mind makes the setter private and the getter public, but this example is not practical if the data members are > 5-10... How would you make a entity class/struct such that the setter is "private" and the "getter" is "public", without making the constructor taking in all the data member variables.

Thanks in advance


Solution

  • What about setting your Creator as friend to class EntityX:

       class EntityX
        {
          friend class Creator;
          public:
            EntityX(int x, int y) : x(x), y(y)
            {}
            int GetX() const {return x;}
            int GetY() const {return y;}
          private:
            int x,y; // Effective C++ third edition, Item 22: Declare data members private
        };
    

    Update:

    Or you could use templatized friend-ship, see code below:

    #include <iostream>
    #include <memory>
    
    template<class T>
    class EntityX
      {
      friend T;
      public:
        EntityX(int x, int y) : x(x), y(y) {}
        int GetX() const {return x;}
        int GetY() const {return y;}
      private:
        int x,y; // Effective C++ third edition, Item 22: Declare data members private
      };
    
    struct Creator
      {
        static const std::shared_ptr<EntityX<Creator>> create() 
          {  
          std::shared_ptr<EntityX<Creator>> entity = std::make_shared<EntityX<Creator>>(1,2);
          entity->x = 1;
          entity->y = 2;
          return entity;
          }
      };
    
    int main()
    {
      std::shared_ptr<EntityX<Creator>> const E = Creator::create();
      std::cout << E->GetX() << ", " << E->GetY() << std::endl;
    
      return 0 ; 
    }