Как сделать переменную недоступного класса

Мне интересно, возможно ли сделать переменную класса недоступной внутри этого класса? Единственный способ изменить значение этой переменной будет через установщик класса. Например:

class foo
{
private:
int m_var;
bool m_isBig;
void setVar(int a_var)
{
// do something before setting value, like emitting signal
m_var = a_var;
}
void method()
{
int copy = m_var; // ok
m_var = 5; // error!
setVar(101); // ok
doSomething();
}
void doSomething()
{
if(m_var > 5)
{ m_isBig = true; }
else
{ m_isBig = false; }
}
};

Я знаю, что я мог бы написать другой класс только с помощью setter и getter, но тогда у меня не будет доступа к другим методам / переменным из класса foo (encapsulation!). Я думаю, что это может быть распространенной проблемой, и для этого может быть какой-то шаблон проектирования, но я не могу его найти.

РЕДАКТИРОВАТЬ:
Я отредактировал код, чтобы было понятно, что я хочу делать в сеттере.

1

Решение

Я не знаю шаблона для этого, но одна возможность — заключить член во вложенный класс. Я думаю, что это также лучший стиль, поскольку создание нового типа выражает намерение, что этот член не просто целое число, а, напротив, имеет уникальное поведение.

class foo {
class MVar {
public:
MVar(foo* parent, int value = 0) : m_parent(parent), m_value(value) {}
MVar& operator=(const MVar&) = delete; // disable assignment
operator int() const { return m_var; }
void set(int new_value) {
// do something, possibly with m_parent
// nested classes have access to the parent's private members
m_value = new_value;
}
private:
foo* m_parent;
int m_value;
} m_var;
void method() {
int copy = m_var; // ok
m_var = 5;        // error
MVar.set(101);    // ok
}
};

Это не совсем то, что вы хотите, так как m_var не действительно иметь тип int, но это то, что нужно учитывать.

0

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

Вы не можете сделать точно, что вы спрашиваете в C ++. Все переменные в классе видны всем методам в классе, независимо от того, являются ли они открытыми или закрытыми.

Вопрос, который вы хотите задать себе: почему класс хочет скрывать вещи от себя самого? Интерфейс класса — это граница между внутренней реализацией класса и услугами, которые он предоставляет внешнему миру. Вы либо внутри класса, либо снаружи.

Имея это в виду, возможно, вы используете такой случай, когда написание дополнительного класса является подходящей вещью?

0

Вы можете заключить целое число в специальный класс и определить только setVar(), но не оператор присваивания int

class M_type
{
int m_var;
public:
explicit M_type(int m) : m_var{m} {}
operator int() const { return m_var; }
void setVar(int a_var) { m_var = a_var; }
};

class foo
{
M_type m_var;
bool m_isBig;
public:
explicit foo(int m) : m_var{m} {};

void method()
{
int copy = m_var; // OK, calls operator int()
m_var = 5; // error, no operator=(int)
m_var.setVar(101); // OK, calls setVar(int)
doSomething();
}

void doSomething()
{
if(m_var > 5)
{ m_isBig = true; }
else
{ m_isBig = false; }
}
};

Не забудьте дать M_type explicit конструктор принимает intи только неявное преобразование operator int() который действует как «добытчик». Если вы также сделаете конструктор неявным, сгенерированное компилятором присваивание operator=(M_type const&) сможет преобразовать аргумент 5 для M_type,

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector