我最近和 Bjarne Stoustrup 一起参加了一场讲座,他在谈论 c++ 11 以及它为什么有意义。
他的一个新的令人敬畏的例子是移动构造函数的新闻'&&'符号。
然后我想回家并开始思考,“我什么时候需要这样的东西?”。
我的第一个例子是下面的代码:
class Number {
private:
int value;
public:
Number(const int value) : value(value){
cout << "Build Constructor on " << value << endl;
}
Number(const Number& orig) : value(orig.value){
cout << "Copy Constructor on " << value << endl;
}
virtual ~Number(){}
int toInt() const{
return value;
}
friend const Number operator+(const Number& n0, const Number& n1);
};
const Number operator+(const Number& n0, const Number& n1){
return Number(n0.value + n1.value);
}
int main(int argc, char** argv) {
const Number n3 = (Number(2) + Number(1));
cout << n3.toInt() << endl;
return 0;
}
这段代码正是移动构造函数应该解决的问题。n3 变量由对“+”运算符返回的值的引用构成。
除了这是运行代码的输出:
Build Constructor on 1
Build Constructor on 2
Build Constructor on 3
3
RUN SUCCESSFUL
输出显示的是复制构造函数永远不会被调用——这是在优化关闭的情况下。我很难扭曲代码的手臂以使其运行复制构造器。将结果包装在 std::pair 中就可以了,但这让我一直在思考。
运算符算术中移动构造函数的参数实际上是一个失败的参数吗?
为什么不调用我的复制构造函数以及为什么调用它:
using namespace std;
class Number {
private:
int value;
public:
Number(const int value) : value(value){
cout << "Build Constructor on " << value << endl;
}
Number(const Number& orig) : value(orig.value){
cout << "Copy Constructor on " << value << endl;
}
virtual ~Number(){}
int toInt() const{
return value;
}
friend const std::pair<const Number, const Number> operator+(const Number& n0, const Number& n1);
};
const std::pair<const Number, const Number> operator+(const Number& n0, const Number& n1){
return make_pair(Number(n0.value + n1.value), n0);
}
int main(int argc, char** argv) {
const Number n3 = (Number(2) + Number(1)).first;
cout << n3.toInt() << endl;
return 0;
}
带输出:
Build Constructor on 1
Build Constructor on 2
Copy Constructor on 2
Build Constructor on 3
Copy Constructor on 3
Copy Constructor on 2
Copy Constructor on 3
Copy Constructor on 2
Copy Constructor on 3
3
RUN SUCCESSFUL
我想知道逻辑是什么以及为什么配对运算符基本上会破坏性能?
更新:
我做了另一项修改,发现如果我替换make_pair
为该对的实际模板化构造函数,pair<const Number, const Number>
这会减少复制构造函数被触发的次数:
class Number {
private:
int value;
public:
Number(const int value) : value(value){
cout << "Build Constructor on " << value << endl;
}
Number(const Number& orig) : value(orig.value){
cout << "Copy Constructor on " << value << endl;
}
virtual ~Number(){}
int toInt() const{
return value;
}
friend const std::pair<const Number, const Number> operator+(const Number& n0, const Number& n1);
};
const std::pair<const Number, const Number> operator+(const Number& n0, const Number& n1){
return std::pair<const Number, const Number>(Number(n0.value + n1.value), n0);
}
int main(int argc, char** argv) {
const Number n3 = (Number(2) + Number(1)).first;
cout << n3.toInt() << endl;
return 0;
}
输出 :
Build Constructor on 1
Build Constructor on 2
Build Constructor on 3
Copy Constructor on 3
Copy Constructor on 2
Copy Constructor on 3
3
RUN SUCCESSFUL
所以看起来使用make_pair
是有害的吗?