C++ – How to ensure that a member variable is initialized before calling a class method

c

There's a class with a parametrized constructor that initializes a member variable. All public methods of the class then use this member variable to do something.

I want to ensure that the caller always creates an object using the parametrized constructor (there is also a setter for this member variable) and then call that object's methods. In essence, it should be impossible for the caller to call any method without setting a value to the member variable (either by using the parametrized constructor or the setter). Here's the catch – there is just one method that itself generates a value to be initialized in the member variable (and returns it) – and to call that function, one would need a default constructor.

Currently, a caller can simply make an object using the default constructor and then call that object's method – I want to avoid checking whether or not the member variable is set in each and every one of the 20-odd methods of the class (and throw an exception if it is not) – except for the one method mentioned above.

Though a runtime solution is acceptable (better than the one I mentioned above); a compile-time solution is preferable so that any developer will not be allowed to make that mistake and then waste hours debuggging it!

Update: Here's an artist's impression of the current implementation in code:

class MyClass
{
private:
string m_strProperty;

void InternalNonStaticMethod(int iSomeParam);

public:
MyClass(string strValue)
{
m_strProperty = strValue;
}

MyClass() {}

void setProperty(string strValue)
{
    m_strProperty = strValue;
}

string MethodOddManOut()
{
    /* Do some computations to generate a value for the property */
    string strGeneratedValue("");
    InternalNonStaticMethod(4);
    /* ... */
    return strGeneratedValue;  // The value has to be returned and this method cannot simply update the member due to design issues that are beyond the realm of this question
}

void MethodLikeEveryoneElse()
{
    /* Do some computation based on the property */
    string strTemp = m_strProperty + "EXTEND";

    /* If strProperty is empty/garbage then this is going to fail miserably
       Trying to avoid the following snippet at 20 other similar methods:
       if (!strProperty.empty()) {
           strTemp = m_strProperty + "EXTEND";
       } else {
           throw exception
       }
    */
}

void MethodLikeEveryoneElse2()
{
    /* Similar to the above method */
}

}

The caller would be a function in some other class using it like this:

void MethodThatUsesThis()
{
    MyClass objA;
    m_strHandle = objA.MethodOddManOut();  // Save the handle as a member of this object

    /* Some other lines of code */

    objA.setProperty(strHandle);
    objA.MethodLikeEveryoneElse();
}

void AnotherMethodThatUsesThisLater(string strHandle)
{
    MyClass objA(strHandle);  // The handle that the above method received was passed to this method since they are in different classes
    objA.MethodLikeEveryoneElse2();
}

This code snippet is bound to raise tons of allegations on the horrendous design that is being implemented – but my only defense is, this is legacy code (ha! you saw this coming) and I only have the right to change anything in class A (it's more of an API and a library module) but the caller is not in my jurisdiction.

Best Answer

If MethodOddManOut() does not take arguments, just call it in your default constructor:

class MyClass {
     // ...
     public:

     MyClass() : m_strProperty( MethodOddManOut()) {}

     // ...
}
Related Topic