2011-11-03 125 views
0

我学习C++,遇到了一些奇怪的问题,我无法在C++书籍或Web上找到任何信息。下面的代码只是对转换构造函数的测试:Test(int)。 testFunction在需要Test对象的地方获取int值,并使用转换构造函数创建一个Test对象以发送给该函数。这按预期工作。隐式使用转换构造函数需要复制构造函数

#include <iostream> 
using namespace std; 

class subClass { 
public: 
    subClass(int); 
    subClass(subClass&); 
}; 

subClass::subClass(int i) {}; 
subClass::subClass(subClass& i) {}; 

class Test { 
public: 
    Test(const Test&); 
    Test(int); 
    subClass sub; 
}; 

Test::Test(const Test &) 
    : sub(1) {}; 

Test::Test(int in) 
    : sub(1) {}; 

void testFunction(Test in) { 
    cout << "testfunction\n"; 
}; 

int main() { 

    testFunction(4); 
} 

但是,如果我从测试类中删除拷贝构造函数测试(const的测试&)我得到如下所示的错误消息。但复制构造函数从来没有使用过,所以它为什么需要?

example.cpp: In function `int main()': 
example.cpp:32: error: no matching function for call to `Test::Test(Test)' 
example.cpp:13: note: candidates are: Test::Test(Test&) 
example.cpp:24: note:     Test::Test(int) 
example.cpp:32: error: initializing argument 1 of `void testFunction(Test)' from result of `Test::Test(int)' 

附加信息: 我注意到,无论是去除子类中的拷贝构造函数或参照testFunction传递参数能够编译功能,不测试的拷贝构造函数。我在cygwin中使用gnu g ++编译器。

回答

3

因为:

void testFunction(Test in) 

你路过价值Test对象,调用拷贝构造函数。

+0

添加一行以从拷贝构造函数打印输出表明它没有被调用。 – snowape

+2

@snowape这可能是因为在代码生成时,拷贝构造函数由于返回值优化而被忽略。然而,RVO并未改变复制构造函数在编译时必须可用的事实。这是我最好的猜测。 –

+0

对不起,我在回答时并没有真正注意'main()',我只是看到错误在抱怨什么。我同意迈克尔关于它实际上没有被调用的原因。 –

0

另一种解释的问题:
如果从 的Test类中删除拷贝构造函数Test(const Test&),你必须要使用编译器生成的拷贝构造函数,它会调用subClass sub的拷贝构造函数。但是您将其定义为subClass(subClass&),这不符合对话。因此,如果您将其更改为subClass(const subClass&),则可以立即删除Test(const Test&)

+0

感谢您的额外信息。现在我看到子类是如何参与的。 – snowape