2012-02-05 47 views
2

我和我的联合编码器经常忘记按引用传递(大)对象,而是传递值。这可能会损害性能。在这种情况下可以配置编译器来警告我吗?是否有可能在一堆C++源文件中自动检测到它......也许是某人已经编写过的正则表达式?自动检测按值传递给C++函数的对象

更新: 感谢球员为您的有益答案。所有答案的一个问题是,他们只适用于我写的课程......不适用于现有的课程,如std::vector。我可以对它们进行子类化,但它太单调乏味了。

+3

使用正则表达式绝对不是正确的工具。即使您可以确定不通过引用传递的参数,但不知道这些类型有多大也无济于事。我没有具体的答案,但我建议您查看静态代码分析工具。 – 2012-02-05 02:43:16

+4

您可以禁用大对象的复制构造函数。 – Johnsyweb 2012-02-05 02:50:15

+1

http://www.boost.org/doc/libs/1_49_0_beta1/libs/utility/utility.htm#Class_noncopyable – Anycorn 2012-02-05 02:56:33

回答

1

只需制作大对象私有的拷贝构造函数和运算符=。在QT中,他们为该Q_DISABLE_COPY()做了特殊的宏。

3

您可以将类型的复制构造函数声明为private - 由于在按值传递对象时会调用复制函数,因此在您传值的任何调用站点,编译时代码都会出错。

如果您的编译器支持,您还可以使用新的c++11支持delete不需要的构造函数/析构函数。查看详细信息here

如果您确实需要在您的代码中使用copy ctor,那么另一个选项是在copy ctor中添加一个调试断点。然后,您可以逐步完成程序的调试版本,并检查拷贝文件的调用时间。

希望这会有所帮助。

编辑:既然你正在寻找检测复制ctor在标准容器上使用的东西是不那么简单。你可以尝试沿着these行,这是一个超级丑恶的黑客,通过包装类与一个禁用的copy-ctor委托所有std::vector实例。

请注意代码中的警告。我只会用这种东西来识别你的传值问题,然后删除它 - 恢复为干净使用std::vector

如果你想永久禁用标准容器的复制,你可以编写自己的包装器封装(而不是继承)标准容器的类。你可以做

+0

是否有适用于现有类的东西..就像'std :: vector'? – 2012-02-07 01:51:49

+0

@AbhishekAnand:检查编辑。 – 2012-02-07 23:03:59

+0

感谢您的回答。我很感激。制作包装是一个好主意。但我想知道是否可以做一些不那么乏味的事情 – 2012-02-08 23:42:17

2

一种方法是让您的重物从类继承一样:

struct heavy { 
    struct heavy_copy_ctor_invoked {}; 
    heavy(const heavy&) { 
     typename boost::mpl::print<heavy_copy_ctor_invoked>::type _; 
    } 
}; 

struct foo : heavy { ... 

每次重拷贝构造函数被调用时,MPL将抛出一个警告。