在这个例子中,使用C ++赋值运算符而不是复制构造函数?

时间:2010-06-14 23:40:21

标签: c++

作为正在尝试升级C ++技能的持续过程的一部分,我试图打破一些旧习惯。我的旧学校C程序员倾向于写这个;

void func( Widget &ref )
{
    Widget w;  // default constructor
    int i;
    for( i=0; i<10; i++ )
    {
        w = ref;  // assignment operator 
        // do stuff that modifies w
    }
}

这很有效。但我认为以下内容更接近最佳实践;

void func( Widget &ref )
{
    for( int i=0; i<10; i++ )
    {
        Widget w = ref; // ??
        // do stuff that modifies w
    }
}

至少使用我的Widget类,这很好用。但我不完全明白为什么。我有两个理论;

1)复制构造函数运行10次 2)复制构造函数运行一次,然后赋值运算符运行9次。

这些都让我有点麻烦。 2)特别是看似人为和错误。我缺少第三种可能性吗?

2 个答案:

答案 0 :(得分:9)

您的第一个理论是正确的:复制构造函数被调用十次。这个:

Widget w = ref;

(几乎)与:

相同
Widget w(ref);

第一个称为复制初始化;第二个叫做直接初始化。两者都调用复制构造函数。两者之间的主要区别在于,如果复制构造函数被声明为explicit,则第一个无效,而只要存在可访问的复制构造函数,第二个有效。

您可以通过声明和定义Widget的复制构造函数和复制赋值运算符来验证这一点,并查看每个函数的调用次数。

答案 1 :(得分:2)

当然复制构造函数运行10次!当您迭代for(;;)周期时,在每次迭代时,在大括号内声明的变量将超出范围。如果Widget有一个析构函数,它将被调用10次(可能会遇到性能)。