2016-08-01 60 views
4

我一直在研究由其他人(谁离开公司)启动的C++项目。他写了一段代码,似乎工作得很好,但我无法理解它。C++ 11 /生成的构造函数

这里是下面的代码的简化版本:

有两类:

class Algo_t { 
protected : 
    Matrix_t m_Matrix ; 
public: 
    Algo_t(Matrix_t && Matrix) { 
     DoSomething(); 
    } 
}; 

class Matrix_t { 
protected : 
    std::ifstream & m_iftsream ; 
public: 
    Matrix_t(std::ifstream && ifstream) { 
     DoSomething(); 
    } 
}; 

在主:

有在主函数下面的调用:

char * pMyFileName = agrv[1] ; 
Algo_t MyAlgo(ifstream(pMyFileName)); 

首先,我非常惊讶的是,代码编译没有任何错误becau se没有构造函数Algo_tifstream作为参数。 我更惊讶地发现这个代码工作得很好。

构造函数是由编译器生成还是由C++ 11引入了一些新特性(使用右值...)?

+1

也许类'Matrix_t'有一个'ifstream'铸造运营商,或需要'ifstream'的构造函数?哦,嘿,它确实...这就解释了它...... –

+0

即使修复了一些明显的错误,您的简化版本也不会编译。 –

+1

这与你构造一个带'const char []'的'std :: string'的结构(几乎) 'std :: stringstream(“Hello World!”)' - 你不需要显式地执行'std :: stringstream(std :: string(“Hello World!”))''。 – Holt

回答

8

在C++中,最多允许一个用户定义的转换。您无法直接从ifstream构建Algo_t,但可以使用ifstream构建Matrix_t。因此,在

Algo_t MyAlgo(ifstream(pMyFileName)); 

编译器构建一个临时Matrix_t(您的一个用户定义的转换),然后您使用临时构建MyAlgo

+0

最多一个?如果我们尝试使用更多,会发生什么? – CinCout

+1

@CinCout代码格式不正确。 – Holt

+0

@CinCout它不起作用。假设你有另外一个类'Foo',可以用'Algo_t'构造。 'Foo MyFoo(ifstream(pMyFileName));'不起作用。 – NathanOliver

3

您的矩阵构造函数被隐式调用,因为它需要ifstream&&。如果你把它明确的,它不会工作:

explicit Matrix_t(std::ifstream && ifstream) { 
    DoSomething(); 
} 
4

至于解释here

单参数的构造函数:允许来自 特定类型的隐式转换初始化对象。

因此,存在因构造的隐式转换选项从ifstreamMatrix_t

Matrix_t(std::ifstream && ifstream) 

所以当你叫:

Algo_t MyAlgo(ifstream(pMyFileName)); 

ifstream(pMyFileName)对象转换为Matrix_t对象,然后由施工人员使用Algo_t(Matrix_t && Matrix)