如何告诉编译器不要创建临时对象?

时间:2009-02-06 16:48:38

标签: c++ oop

我正在更改一个过去采用整数参数的旧例程,以便它现在对对象进行const引用。我希望编译器能告诉我调用函数的位置(因为参数类型错误),但是对象有一个构造函数,它接受一个整数,所以编译器创建一个临时对象,而不是失败,传递给它整数,并将对它的引用传递给例程。示例代码:

class thing {
  public:
    thing( int x ) {
        printf( "Creating a thing(%d)\n", x );
    }
};

class X {
  public:
    X( const thing &t ) {
        printf( "Creating an X from a thing\n" );
    }
};


int main( int, char ** ) {
    thing a_thing( 5 );
    X an_x( 6 );
    return 1;
}

我希望X an_x( 6 )不编译,因为没有X构造函数需要int。但它确实编译,输出如下:

Creating a thing(5)
Creating a thing(6)
Creating an X from a thing

如何保留thing( int )构造函数,但不允许临时对象?

2 个答案:

答案 0 :(得分:11)

在事物构造函数中使用explicit关键字。

class thing {
public:
    explicit thing( int x ) {
        printf( "Creating a thing(%d)\n", x );
    }
};

这将阻止编译器在找到整数时隐式调用thing构造函数。

答案 1 :(得分:1)

explicit关键字在我的示例中完美运行,但后来我意识到我的真实世界代码在重载方法上失败了,而不是构造函数。 (我提出的问题与我的实际问题类似,但不一样。)正如Mark Ransom在对已接受答案的评论中指出的那样,explicit仅适用于构造函数。我想出了解决我问题的解决方法,所以我想我会在这里发布。新示例代码:

class thing {
  public:
    thing( int x ) {
        printf( "Creating a thing(%d)\n", x );
    }
};

class X {
  public:
    void do_something( const thing &t ) {
        printf( "Creating an X from a thing\n" );
    }
};


int main( int, char ** ) {
    thing a_thing( 5 );
    X an_x;
    an_x.do_something( 6 );
    return 1;
}

此代码显示与原始代码相同的输出,但我无法使用explicit来修复它。相反,我添加了一个带有int的私有方法:

  private:
    void do_something( int x );

现在,编译器不会创建临时对象,它会出错,因为我试图从类外部调用私有方法。