Domanda

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

È stato utile?

Soluzione

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 ; 
}

Altri suggerimenti

Your getter could return a const& so...

public:
int const& Getter();
private:
int const& Setter(int value);

with "setter" and "getter" are replaced with the name of the variable. so...

public:
int const& X();
private:
int const& X(int value);

you can also write the same thing with this syntax...

const int& X();

just a matter of how you want to write it.

Good luck, I hope i could help.

How about something like:

struct EntityValues
{
   Type1 value1_;
   Type2 value2_;
   (etc for all the members of Entity
};

class Entity
{
  public:
    Entity () : <set default values> 
    {
    }

    // this avoids the sea-of-parameters problem by bundling the data values
    // into a single parameter.  Data can be added to values by name in random order
    // before it is finally used here.
    Entity(const EntityValues & values) : <set members by pulling data from values>
    {

    }

    // individual public getters.
    Type1 getValue1()const { return value1_;}
    <repeat as necessary for other members>

    // get everything at once 
    // (an alternative to individual getters)
    // 
    void exportValues(EntityValues & values) const
    {
       <copy member to values>
    }

    // optional (this violates the "no public setters" constraint
    // but it does it in a controlled manner.
    void update(const EntityValues & values)
    {
       <set members by pulling data from values>
    }

private:
    <setters (if necessary) and members go here
 };

Also EntityValues could be a public, nested structure declared inside Entity (i.e. struct Entity::Values)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top