I'm using a library that has a class with an init
function distinct from its constructor. Every time I make a new instance I need to call, for example:
MyClass a;
a.init();
Since init
is not const
, this prevents me from creating const instances (I can't write const MyClass a
). Is there some way to call init and then declare from "here on out" (I guess for the remainder of the scope) my variable is const
?
This works, but relies on not touching the original variable:
MyClass dont_touch;
dont_touch.init();
const MyClass & a = dont_touch;
Variables can be declared as constants by using the “const” keyword before the datatype of the variable. The constant variables can be initialized once only. The default value of constant variables are zero. A program that demonstrates the declaration of constant variables in C using const keyword is given as follows.
The const keyword prevents us from reassigning the variable, but it doesn't make objects and arrays immutable.
To declare a constant variable in C++, the keyword const is written before the variable's data type. Constant variables can be declared for any data types, such as int , double , char , or string .
A const object can be created by prefixing the const keyword to the object declaration. Any attempt to change the data member of const objects results in a compile-time error. When a function is declared as const, it can be called on any type of object, const object as well as non-const objects.
If you're using C++11 you could use a lambda function
const MyClass ConstantVal = []{
MyClass a;
a.init();
return a;
}();
This allows you to keep the initialization in place while never giving outside access to the mutable object. see also: http://herbsutter.com/2013/04/05/complex-initialization-for-a-const-variable/
You can create a wrapper class and use that instead.
If MyClass has a virtual destructor you can feel safe deriving from it like this:
class WrapperClass : public MyClass
{
public:
WrapperClass()
{
init(); // Let's hope this function doesn't throw
}
};
Or write a class that contains the MyClass instance
class WrapperClass
{
public:
WrapperClass()
{
m_myClass.init(); // Let's hope this function doesn't throw
}
operator MyClass&() {return m_myClass;}
operator const MyClass&() const {return m_myClass;}
private:
MyClass m_myClass;
};
Or write a template to solve this general problem using one of the two solutions above: eg.
template <class T> class WrapperClass : public T
{
public:
WrapperClass()
{
T::init();
}
};
typedef WrapperClass<MyClass> WrapperClass;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With