Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I make a variable _const from now on_?

Tags:

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;
like image 439
Alec Jacobson Avatar asked Apr 30 '14 23:04

Alec Jacobson


People also ask

How do you make variables const?

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.

Can we assign this to const variable?

The const keyword prevents us from reassigning the variable, but it doesn't make objects and arrays immutable.

How do you set a variable to constant in C++?

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 .

How do you make an object const in C++?

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.


2 Answers

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/

like image 103
Lachlan Easton Avatar answered Sep 30 '22 19:09

Lachlan Easton


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;
like image 41
cppguy Avatar answered Sep 30 '22 18:09

cppguy