Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ : How to ensure that a class member variable is modifiable only within a certain method

Tags:

c++

c++11

c++14

I am using C++ 14 with clang on MacOS Sierra. I want to enforce a rule by design. Following is the rule.

I have a member variable in my class say:

unsigned int m_important_num;

There are 4 methods in my class.

fun1();
fun2();
fun3();
fun4();

Objective:
I want only fun2() to be able to change the value of m_important_num.

Question:
Is it possible to make it compiler error if any method other than fun2() changes the variable? One possible way is to declare it const somehow empower fun2() to change const variables? Is this a good solution? Or are their any better solutions?

Secondary question:
Is it a wrong design to try do such a thing?

like image 574
TheWaterProgrammer Avatar asked Nov 14 '17 19:11

TheWaterProgrammer


People also ask

How do you access member variables in a class?

To get the value of a class member variable, pass the class to one of the appropriate class member variable access functions. To get the value of an instance member variable, pass the object to the appropriate instance member variable access function. For example, in FieldAccess.

Does C++ have readonly?

The readonly C++ attribute has the same functionality as the readonly MIDL attribute. If you want to prohibit modification of a method parameter, then use the in attribute.

Can you change the value of a private variable in c++?

Sure you can access and modify private variables but you do it only through exposed public interface. Not anyone can modify the data directly (Neither derived classes or any global functions unless another class or function is a friend of that class).

How do you initialize a const member variable in a class?

To initialize the const value using constructor, we have to use the initialize list. This initializer list is used to initialize the data member of a class. The list of members, that will be initialized, will be present after the constructor after colon. members will be separated using comma.


1 Answers

Sort of, with additional layer:

class S1 {
public:
    void fun2() { /*Modify m_important_num */ }
    unsigned int getImportantNum() const { return m_important_num;}
private:
    unsigned int m_important_num;
};
class S2 : private S1
{
public:
    void fun1();
    using S1::fun2; // or void fun2() {S1::fun2();}
    void fun3();
    void fun4();
};

As Yakk commented, if func2 need access to S2 members, CRTP can solve that:

template <typename Derived>
class S1 {
public:
    void fun2() { asDerived().foo3(); /*Modify m_important_num */ }
    unsigned int getImportantNum() const { return m_important_num;}
private:
    Derived& asDerived() { return stataic_cast<Derived&>(*this); }
private:
    unsigned int m_important_num;
};
class S2 : private S1<S2>
{
    // friend class S1<S2>; // If required.
public:
    void fun1();
    using S1::fun2; // or void fun2() {S1::fun2();}
    void fun3();
    void fun4();
};
like image 98
Jarod42 Avatar answered Sep 30 '22 00:09

Jarod42