从文件实例化:构造函数采用std:ifstream&作为参数

Instantiating from file : constructor taking std:ifstream& as argument

本文关键字:ifstream std 参数 文件 实例化 构造函数      更新时间:2023-10-16

我希望有一个类构造函数来从文件中读取值,所以我定义了一个这样的类:

#include<iostream> 
#include<fstream> 
#include<string>
class aClass
{
    float value;
public:
    aClass(float v) : value(v) {}
    aClass(const aClass& other): value(other.value) {}
    static aClass initFromFile(std::ifstream &); 
};
aClass initFromFile(std::ifstream &is)
{ 
    std::string strBuffer;
    std::getline(is, strBuffer);
    float v = std::stof(strBuffer);
    return aClass(v);
}

我的问题是关于static initFromFile构造函数的。

然后主程序将打开一个文件,读取一个值并实例化该类:

int main()
{
    std::ifstream inFile("value.txt");
    aClass cls(aClass::initFromFile(inFile));
}

代码已编译,但链接时出错:

undefined reference to `aClass::initFromFile(std::basic_ifstream<char, std::char_traits<char> >&)'

为什么inFilestd::ifstream

正如评论中所说:

aClass initFromFile(std::ifstream &is) {}

是自由(非成员(函数的定义。你想要

aClass aClass::initFromFile(std::ifstream &is)

相反。

此外,您的复制构造函数是无用的,可以删除。隐式生成的将做同样的事情。

您误解了错误。它与inFile是否是std::ifstream无关(它是(。问题在于initFromFile函数的实现。

aClass initFromFile(std::ifstream &is)
{
    ... 
}

声明一个与aClass无关的新功能。为了让编译器知道initFromFile确实是aClass::initFromFile,你必须告诉它:

aClass aClass::initFromFile(std::ifstream &is)
//     ^^^^^^^^
{
    ... 
}

但是,initFromFile不使用类内部结构,因此一般的经验法则是它不应该是类的成员。

class aClass
{
    float value;
public:
    aClass(float v) : value(v) {}
    aClass(const aClass& other): value(other.value) {}
};
aClass initFromFile(std::ifstream &is) //stand-alone free function
{ 
    std::string strBuffer;
    std::getline(is, strBuffer);
    float v = std::stof(strBuffer);
    return aClass(v);
}

它可以用作

int main()
{
    std::ifstream inFile("value.txt");
    aClass cls = initFromFile(inFile);
}

不相关的注释:

一个小的改进是使用std::istream定义initFromFile

aClass initFromFile(std::istream &is)

以便您可以将该功能用于更广泛的流,例如 cin .

还要熟悉三、五和零规则。 aClass符合零规则,因此不需要用户定义的复制构造函数。