C++ 学习笔记
类的实例化、拷贝构造函数、析构函数
class Test {
public:
Test(std::string File) {
ifs.open(File);
ifs >> temp;
std::cout << temp << std::endl;
};
~Test() {};
private:
std::ifstream ifs;
std::string temp;
};
int main() {
std::string file = "test.txt";
//Test test(file);
Test test1 = Test(file);
}
其中有两种类的实例化方式:
-
直接调用含参构造函数
Test test(file);
此时为直接创建一个test实例,并调用其含参构造函数进行初始化,可以运行通过;
-
先创建临时实例,再调用拷贝构造函数(实际为赋值操作)
Test test1 = Test(file);
这次在visual studio编译不通过,报
Error C2280 ‘Test::Test(const Test &)’: attempting to reference a deleted function
原因在于Test中显式定义了析构函数,而默认拷贝构造函数对ifs只是浅拷贝,在赋值之后,临时实例将被析构,main结束之后,test1也被析构,这样ifs会被析构两次,即会出错。因此vs为了安全考虑,在显式定义析构函数后,如果类成员里有引用类型,则会删除默认拷贝构造函数。
备注:
以下实例化可运行通过:
Test&& test1 = Test(file);
其中&&代表右值引用。但此时test1只是右边临时实例的一个引用,所以当返回之后,临时实例被析构,test1即是一个已经被西沟的实例。另外Test& test1 = Test(file);
不会编译通过,但原因是&是左值(暂理解为可由标识符访问的变量/实例)引用,而构造函数(或其他函数)返回的临时实例(或变量)是右值,所以不通过。