复制构造函数和级联函数调用

时间:2017-12-06 03:12:36

标签: c++ function c++11 copy-constructor

我跑了这个例子:

#include <cstdlib>
#include <iostream>
#include <istream>
#include <ostream>
using namespace std;
class Weight {
    int k;
    char a[100];
public:
    Weight(int kilos = 0) 
        :k(kilos) {}
    Weight(const Weight& w) 
        : k(w.k) {
        for(int i = 0; i < 100; ++i) this->a[i] = 'a'; 
        cout << "WCC\n";
    }
    friend Weight operator+(const Weight& a, const Weight& b);
    Weight& operator=(const Weight & w) {
        this->k = w.k;
        return *this;
    }
    friend ostream& operator<<(ostream&, const Weight&);
};
Weight operator+(const Weight& a, const Weight& b) {
    cout << "FP\n";
    int newkg = a.k + b.k;
    return Weight(newkg);
}
ostream& operator<<(ostream& out, const Weight& w) {
    out << w.k << " KGs";
    return out;
}
class Container{
    Weight w;
    static Weight totalW;
    static int count;
public:
    Container(){++count;}
    ~Container(){cout << "CD\n";}
    Container& add(Weight weight) {
        this->w = this->w + weight; 
        totalW = totalW + weight;
        cout << "Just added a new item that weighs " << weight << endl;
        return *this;
    }
    static void print() { 
        cout << "We have " << count << " Containers with a total weight " 
                << totalW << endl;
    } 
    friend ostream& operator<<(ostream&, const Container&);
};
Weight Container::totalW;
int Container::count = 0;
ostream& operator<<(ostream& out, const Container& c){
    out << "This container's " << c.w;
    return out;
}
int main(int argc, char** argv) {
    Container c1;

    Weight *w1 = new Weight(1);
    Weight *w2 = new Weight(2);
    Weight *w3 = new Weight(3);

    cout << "Adding items to container...\n";
    c1.add(*w1).add(*w2).add(*w3);

    cout << c1 << endl;

    Container::print();
    return 0;
}

我得到了这个输出:

Adding items to container...
WCC
WCC
WCC
FP
FP
Just added a new item that weighs 1 KGs
FP
FP
Just added a new item that weighs 2 KGs
FP
FP
Just added a new item that weighs 3 KGs
This container's 6 KGs
We have 1 Containers with a total weight 6 KGs
CD

在调用任何级联函数之前,您可以看到Weight类的复制构造函数被调用了三次(输出行2-4)。我一直认为,在调用任何复制构造函数来设置第二个函数调用之前,将执行最左边的函数调用。

更具体地说,我认为应该发生的事情: WCC - &gt; c1.add(* w1) - &gt; WCC - &gt; .add(* w2) - &gt; WCC - &gt; 。新增(* W3)。

我认为这是必要的,因为函数参数将存储在函数的堆栈框架中。因此,需要在调用参数的复制构造函数之前设置堆栈帧。显然,我错了。

这让我觉得函数参数存储在堆栈框架以外的其他地方。那么,在哪里?

不要介意可怕的编码风格。显然,这并不意味着在生产代码中。

1 个答案:

答案 0 :(得分:0)

我认为这是一个基本的编译器优化。由于不应该从提供的参数初始化函数的参数,因此编译器可以通过重新排列它们来进行必要的优化。这就是为什么你看到副本构造函数一次调用all。