Инкапсуляция данных, чтобы установщик был закрытым, а получатель — открытым

Мне было интересно, как лучше всего создать объект данных в C ++, где «установщик» является закрытым, а «получатель» — открытым. Т.е. создатель объекта должен иметь возможность устанавливать данные, но пользователь / потребитель / клиент может получить только данные.

Давайте рассмотрим сущность 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
}

И метод класса, который создает сущность и возвращает ее клиенту:

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

return entity;
}

Это, на мой взгляд, делает установщик частным, а получатель общедоступным, но этот пример не практичен, если члены данных> 5-10 … Как бы вы сделали класс / структуру сущности таким, чтобы установщик был «частным» и «getter» является «public», не заставляя конструктор принимать все переменные-члены данных.

заранее спасибо

2

Решение

Как насчет настройки вашего творец как friend в 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
};

Обновить:

Или вы можете использовать шаблонизированное дружественное судно, см. Код ниже:

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

Другие решения

Ваш получатель может вернуть констант& так…

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

с «setter» и «getter» заменяются на имя переменной. так…

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

Вы также можете написать то же самое с этим синтаксисом …

const int& X();

просто вопрос, как вы хотите это написать.

Удачи, я надеюсь, что смогу помочь.

0

Как насчет чего-то вроде:

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

Также EntityValues может быть публичной, вложенной структурой, объявленной внутри Entity (Т.е. struct Entity::Values)

0
По вопросам рекламы [email protected]