c ++:按值复制到函数params在vs2012中生成两个对象

use*_*018 23 c++ gcc visual-c++ gcc4.7 visual-studio-2012

这里的代码在g ++ 4.7和vs2012(cl17)中产生不同的输出.

#include <iostream>

using namespace std;

class A
{
public:
    A() { cout << "1" << endl; }
    ~A() { cout << "2" << endl; }
};

class B : public A
{
public:
    B() { cout << "3" << endl; }
    ~B() { cout << "4" << endl; }
};

void func(A a) {}

int main()
{
    B b;
    func(b);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

GCC输出是13242,而cl输出132242.

为什么cl编译器A在堆栈上复制时会产生第二个对象,出于什么目的?

Alo*_*ave 5

这似乎是一个编译器错误.
C++标准不使用术语对象切片,您将该类型的对象传递B给接收该类型参数的函数A.编译器将应用通常的重载决策来查找适当的匹配.在这种情况下:
Base类A 具有编译器提供的复制构造函数,它将引用A并且在没有其他转换函数的情况下,这是最佳匹配,并且应该由编译器使用.

请注意,如果可以获得更好的转换,则会使用它.例如:如果A有一个构造函数A::A( B const& ),除了复制构造函数之外,还会使用这个构造函数,而不是复制构造函数.

  • "A"的显式琐碎复制构造函数修复了VS2010中的问题,这对我来说没有多大意义. (4认同)

BЈо*_*вић -3

您遇到了编译器的错误。

正确的功能解释如下:


该函数func需要创建对象的副本(但要注意切片)。

那么,发生的事情是这样的:

int main()
{
    // create object B, which first creates the base object A
    B b;
    // create object A, using this copy constructor : A( const B& )
    func(b);
}
Run Code Online (Sandbox Code Playgroud)

当复制构造的对象 A 在调用结束时被销毁时,会进行额外的 ~A() 调用func

  • 在“cl 输出”中,在“func()”末尾有两次对“~A”的调用。这似乎是个问题。 (5认同)
  • @BЈовић 应该发生什么已经在问题中了;这只是重述。 (2认同)