我可以从现在开始变量_const吗?

Ale*_*son 20 c++ constructor const reference

我正在使用一个具有init与其构造函数不同的函数的类的库.每次我创建一个新实例时我都需要调用,例如:

MyClass a;
a.init();
Run Code Online (Sandbox Code Playgroud)

既然init不是const,这就阻止了我创建const实例(我无法写const MyClass a).有没有办法调用init然后从"here out out"声明(我猜对于范围的其余部分)我的变量是const

这有效,但依赖于不触及原始变量:

MyClass dont_touch;
dont_touch.init();
const MyClass & a = dont_touch;
Run Code Online (Sandbox Code Playgroud)

Lac*_*ton 16

如果您使用的是C++ 11,则可以使用lambda函数

const MyClass ConstantVal = []{ 
    MyClass a;
    a.init(); 
    return a; 
}();
Run Code Online (Sandbox Code Playgroud)

这允许您保持初始化到位,而不允许外部访问可变对象.另见:http: //herbsutter.com/2013/04/05/complex-initialization-for-a-const-variable/


cpp*_*guy 9

您可以创建一个包装类并使用它.

如果MyClass有一个虚拟析构函数,你可以感觉到它是安全的,如下所示:

class WrapperClass : public MyClass 
{
public:
    WrapperClass()
    {
        init(); // Let's hope this function doesn't throw
    }
};
Run Code Online (Sandbox Code Playgroud)

或者编写一个包含MyClass实例的类

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;
};
Run Code Online (Sandbox Code Playgroud)

或者使用以上两种解决方案之一编写模板来解决这个一般问题:例如.

template <class T> class WrapperClass : public T
{
public:
    WrapperClass()
    {
        T::init();
    }
};

typedef WrapperClass<MyClass> WrapperClass;
Run Code Online (Sandbox Code Playgroud)


R S*_*ahu 5

创建一个包装前两行的函数,并为您提供一个准备好的对象.

MyClass makeMyClass()
{
   MyClass a;
   a.init();
   return a;
}

// Now you can construct a const object or non-const object.
const MyClass a = makeMyClass();
MyClass b = makeMyClass(); 
Run Code Online (Sandbox Code Playgroud)

更新

makeMyClass()每次调用函数时,使用都涉及构造和销毁临时对象.如果这成为一项重大成本,makeMyClass()可以改为:

MyClass const& makeMyClass()
{
   static bool inited = false;
   static MyClass a;
   if ( !inited )
   {
     inited = true;
     a.init();
   }
   return a;
}
Run Code Online (Sandbox Code Playgroud)

如前所述,它的用法将继续有效.另外,曾经也可以这样做:

const MyClass& c = makeMyClass();
Run Code Online (Sandbox Code Playgroud)

  • @mangledorf我不确定这一点,但[返回值优化](https://en.wikipedia.org/wiki/Return_value_optimization)可能很有用.所以,如果我理解正确,如果你使用`-O3`,我认为你不必担心这一点.只是一个想法. (3认同)