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++也是我的母语编程语言。我读了其中的一些文章很开心:谢谢你花了这么多时间,但你似乎也没有抓住重点,就像托马斯(见第一篇文章的评论)和查尔斯·贝利一样。