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/
您可以创建一个包装类并使用它.
如果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)
创建一个包装前两行的函数,并为您提供一个准备好的对象.
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)
| 归档时间: |
|
| 查看次数: |
587 次 |
| 最近记录: |