Search code examples
c++classobjectoop

How to change values of private variables for all objects from under the same class?


How to make the variable m_i have its own value for each object, and when a certain function is called, the value of m_i for all objects should be set to zero, no matter how many objects of the class CMyClass were created?

#include <iostream>

using namespace std;
class CMyClass {
public:
   static int m_i;
};

int CMyClass::m_i = 0;
CMyClass myObject1;
CMyClass myObject2;

int main() {
   cout << myObject1.m_i << endl;
   cout << myObject2.m_i << endl;

   myObject1.m_i = 1; // set m_i to 1 for first object
   cout << myObject1.m_i << endl;
   cout << myObject2.m_i << endl;

   myObject2.m_i = 2; // set m_i to 2 for second object
   cout << myObject1.m_i << endl;
   cout << myObject2.m_i << endl;

   CMyClass::m_i = 0; // set m_i to zero for all objects
   cout << myObject1.m_i << endl;
   cout << myObject2.m_i << endl;
}

Output

0
0
1
1
2
2
0
0

Expected output should be:

Output

0
0
1
0
1
2
0
0

UPD The solution for MCU usage was proposed by @Lasersköld and works without any additionally libraries:

#include <iostream>

using namespace std;
class CMyClass {
public:

    // The member variable should not be static because
    // it is unique for each class instance.
    int m_i;
};

CMyClass instances[2];

void resetInstances() {
    for (auto &instance: instances) {
        instance.m_i = 0;
    }
}

int main() {

   cout << instances[0].m_i << endl;
   cout << instances[1].m_i << endl;

   instances[0].m_i = 1;
   cout << instances[0].m_i << endl;
   cout << instances[1].m_i << endl;

   instances[1].m_i = 2;
   cout << instances[0].m_i << endl;
   cout << instances[1].m_i << endl;

   resetInstances();
   cout << instances[0].m_i << endl;
   cout << instances[1].m_i << endl;
}

Output:

0
1
0
1
2
0
0

Solution

  • Save each instance in a static list like so:

    #include <iostream>
    #include <vector>
    
    using namespace std;
    class CMyClass {
    public:
    
        CMyClass(int i): m_i{i} {
            instances.push_back(this);
        }
    
        // ~CMyClass() {
        // ... handle removal if nessesary. check out std::remove(...)
        // }
    
        int m_i = 0;
    
        static std::vector<CMyClass*> instances;
    
        static void reset() {
            for (auto &instance: instances) {
                instance->m_i = 0;
            }
        }
    };
    
    std::vector<CMyClass*> CMyClass::instances;
    
    int main() {
        CMyClass myObject1{0};
        CMyClass myObject2{0};
    
       cout << myObject1.m_i << endl;
       cout << myObject2.m_i << endl;
    
       myObject1.m_i = 1;
       cout << myObject1.m_i << endl;
       cout << myObject2.m_i << endl;
    
       myObject2.m_i = 2;
       cout << myObject1.m_i << endl;
       cout << myObject2.m_i << endl;
    
        
       CMyClass::reset();
       cout << myObject1.m_i << endl;
       cout << myObject2.m_i << endl;
    }
    

    Possible microcontroller (heapless) implementation.

    #include <iostream>
    #include <array>
    
    using namespace std;
    class CMyClass {
    public:
    
        // The member variable should not be static because
        // it is unique for each class instance.
        int m_i = 0;
    };
    
    // If you use microcontrollers that does not implement the standar library
    // replace this with
    // CMyClass instances[2];
    std::array<CMyClass, 2> instances;
    
    void resetInstances() {
        for (auto &instance: instances) {
            instance.m_i = 0;
        }
    }
    
    int main() {
    
       cout << instances.at(0).m_i << endl;
       cout << instances.at(1).m_i << endl;
    
       instances.at(0).m_i = 1;
       cout << instances.at(0).m_i << endl;
       cout << instances.at(1).m_i << endl;
    
       instances.at(1).m_i = 2;
       cout << instances.at(0).m_i << endl;
       cout << instances.at(1).m_i << endl;
    
       resetInstances();
       cout << instances.at(0).m_i << endl;
       cout << instances.at(1).m_i << endl;
    }
    

    Note: I do not recommend using the name convention with m_ for public class members. In this case i would call the member variable m_i for simply i and then use m_... for private variables that is only used in private functions of the class.