如何声明一个对象但不运行构造函数?

时间:2013-09-12 08:12:39

标签: c++ constructor

我需要一个MyClass对象用于main()的整个生命周期,但只有当某个标志useMyObject为真时才需要。

  • 我相信声明MyClass myObject运行构造函数。真的吗?我无法查找它。
  • 如果是,我怎么能避免两次调用构造函数?

构造函数抓取一个我只想抓取一次的资源,并且只有在设置了标志时才抓取。这是我的代码:

int main() {
    MyClass myObject;
    // ...
    if ( useMyObject ) {
        myObject = MyClass(42);
    }
    // ...
}

3 个答案:

答案 0 :(得分:6)

一种简单的方法是使用std::unique_ptr

std::unique_ptr<MyClass> myObjectPtr;

if(useMyObject)
    myObjectPtr.reset(new MyClass(42));

if(myObjectPtr)
    myObjectPtr->method();

但请注意,它需要堆分配,实际上可能比“空”构造更昂贵。为了避免堆分配的成本,可以使用与指针类似的boost::optional,但实际上对象的存储是在堆栈上分配的:

boost::optional<MyClass> myObject;

if(useMyObject)
    myObject = MyClass(42);

if(myObject)
    myObject->method();

正如您在上述任何一种情况中所看到的,代码将充满条件。

如果允许更改MyClass,我建议使用非参数构造函数构造一个“空”对象。您只需要将对象构造为实际上什么都不做的状态,但是如果使用它不应该使应用程序崩溃。这个空洞的建筑应该很便宜,无论如何只需要一次性费用。

如果你可以将对象移动到实际使用它的范围并且完全避免未初始化/空对象,那就更好了:

if(useMyObject) {
    MyClass myObject(42);
    // use the object here and nowhere else.
}

答案 1 :(得分:2)

是的,在声明对象时将运行构造函数。
您可以使用std::unique_ptr代替,只需在需要时初始化对象。
但是,这可能会使您的代码充满ifs,因此可能有更好的方法来安排代码。

答案 2 :(得分:0)

MyClass& getMyObject()
  static MyClass myObject(42);
  return myObject;
}

如果您实际上不需要该对象,但只是想确保它存在,甚至可以调用:

int main() {
    // ...
    if ( createMyObjectNow ) {
        getMyObject();
    }
    // ...
}