我跑了这个例子:
#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)。
我认为这是必要的,因为函数参数将存储在函数的堆栈框架中。因此,需要在调用参数的复制构造函数之前设置堆栈帧。显然,我错了。
这让我觉得函数参数存储在堆栈框架以外的其他地方。那么,在哪里?
不要介意可怕的编码风格。显然,这并不意味着在生产代码中。
答案 0 :(得分:0)
我认为这是一个基本的编译器优化。由于不应该从提供的参数初始化函数的参数,因此编译器可以通过重新排列它们来进行必要的优化。这就是为什么你看到副本构造函数一次调用all。