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

时间:2018-01-05 18:50:15

标签: c++

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

#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> >&)'

为什么inFile不是std::ifstream

2 个答案:

答案 0 :(得分:1)

正如评论中所述:

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

是免费(非会员)功能的定义。你想要

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

代替。

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

答案 1 :(得分:0)

您误解了错误。它与RunTimeImage是否为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); }

定义initFromFile
std::istream

这样您就可以将该函数用于更广泛的流,例如aClass initFromFile(std::istream &is)

同时熟悉Rules of Three, five and Zerocin符合Zero规则,因此不需要用户定义的复制构造函数。