C++ 编译器中的复制方法优化
我有以下代码:C++ 编译器中的复制方法优化,c++,copy,containers,compiler-optimization,C++,Copy,Containers,Compiler Optimization,我有以下代码: void Stack::operator =(Stack &rhs) { //do the actual copying } Stack::Stack(Stack &rhs) //copy-constructor { top=NULL; //initialize this as an empty stack (which it is) *this=rhs; //invoke assignment operator } Stack&
void Stack::operator =(Stack &rhs)
{
//do the actual copying
}
Stack::Stack(Stack &rhs) //copy-constructor
{
top=NULL; //initialize this as an empty stack (which it is)
*this=rhs; //invoke assignment operator
}
Stack& Stack::CopyStack()
{
return *this; //this statement will invoke copy contructor
}
它是这样使用的:
unsigned Stack::count()
{
unsigned c=0;
Stack copy=CopyStack();
while (!copy.empty())
{
copy.pop();
c++;
}
return c;
}
从CopyStack声明中删除引用符号(返回一个副本而不是引用)在VisualStudio2008中没有任何区别(就调用复制的次数而言)。我猜它会得到优化-通常它应该首先为返回值创建一个副本,然后再次调用赋值操作符将其赋值给变量sc
您在不同的编译器中使用这种优化的经验是什么
问候,,
Dženan此语句是从
CopyStack()
的返回值对名为copy
的堆栈进行复制初始化。没有任务
Stack copy=CopyStack();
此函数中的注释不正确。由于返回值是引用,因此不调用复制构造函数
Stack& Stack::CopyStack()
{
return *this; //this statement will invoke copy contructor
}
这意味着原始初始化实际上是从*这个变量复制构造
如果返回值是by value,那么复制初始化将来自临时的,但编译器可以有效地消除该临时的
我看不出CopyStack
函数有什么意义。更惯用的做法是只执行直接初始化:
Stack copy(*this);
如果我理解正确,您可以对堆栈对象进行原型化并返回原型,这可能会带来一些性能,但您必须小心内存资源的对象所有权
如果您愿意,您可以使用原型工厂设计模式。我想您需要的是RVO(返回值优化)和NRVO(命名为返回值优化)。编译器优化是一个庞大的主题,如果我开始键入描述,它将花费太长的时间!看看这个。。。它很好地解释了这一点。放在一边:你的复制构造函数和操作符=
应该使用const
引用。这实际上是一个非常简单的作业——一个只有119行实现的类。每个方法最多被调用几次,并且永远不会被扩展。之所以要问这个问题,是因为它在C++教科书中得到了大量的关注。在这个程序中,性能并不重要——复制堆栈只使用push和pop方法实现——这使得它效率极低。计数本来可以作为私有变量保留,等等。你的问题实际上也是:“在实践中,编译器会消除使用副本初始化的定义中的临时变量吗?”,因为代码中的注释似乎显示了对引用作为返回值的误解,当我写那篇评论时,我希望它能被复制。后来我发现编译后的代码已经按照我想要的方式进行了优化。感谢您花时间发布答案。CopyStack方法的重点是方便记法,或者更好的答案是我第一次编写了CopyStack方法,但当最初的想法不起作用时,却被这三种方法的组合所取代。这个控件是复制构造函数的,虽然后来才出现——而这个注释更多的是我自己的。我更希望有人有使用GCC或其他编译器的经验(关于这些东西的优化),并能与我们分享。顺便说一句,GCC和其他大多数编译器一样,应用这两种算法。另外,您可能有兴趣看看C++0x的“移动语义”。移动语义可以消除不必要的对象复制,只需利用这样一个事实,即复制一个临时对象是没有意义的,它没有被任何其他对象引用,并且很快就会被销毁。事实上,我很惊讶编译器对我的代码做了很好的优化,批评C++的批评,??对我来说,C++一直是一种非常强大的语言(我讨厌托管代码!),但是嘿…每个故事都有两个方面,不是吗?我已经看过C++几次了,我觉得很棒,现在我只等最后的规范出现,然后再实现。C++也是我的母语编程语言。我读了其中的一些文章很开心:谢谢你花了这么多时间,但你似乎也没有抓住重点,就像托马斯(见第一篇文章的评论)和查尔斯·贝利一样。