使用参数初始化构造函数

scc*_*ccs 2 c++ constructor class

阅读Andrew Koenig和Barbara E. Moo撰写的"Accelerated C++"的另一个问题,我在关于构造函数(5.1)的章节中,使用了前面的例子.

他们写

我们要定义两个构造函数:第一个构造函数不带参数并创建一个空Student_info对象; 第二个引用输入流并通过从该流中读取学生记录来初始化对象.

导致使用Student_info::Student_info(istream& is) {read(is);}第二个构造函数的例子

将实际工作委托给读取功能.[...]立即读取这些变量的新值.

Student_info堂课是

class Student_info {
public:
    std::string name() const (return n;}
    bool valid() const {return !homework.empty();}
    std::istream& read(std::istream&);

    double grade() const;
private:
    std::string n;
    double midterm, final;
    std::vector<double> homework;
};
Run Code Online (Sandbox Code Playgroud)

既然read已经定义为Student_info类下的函数,为什么需要使用第二个构造函数 - 这不是双重工作吗?为什么不使用默认构造函数,然后使用函数,因为两者都已定义?

acc*_*ews 5

相反,它不是双重工作,它简化了实例化类的调用者的对象初始化

如果每次都需要使用单个构造函数创建类

std::istream is = std::cin;
Student_info si();
si.read(is);
// si.foo();
// si.bar();
// si.baz();
Run Code Online (Sandbox Code Playgroud)

也许可以添加一些可以在构造函数中完成的其他操作.因此,当您需要实例化类时,不必再次编写它们.如果您创建10个实例,则必须编写

(10 -1 =)另外9行,这对于OOP来说不是一个好方法

Student_info::Student_info(istream& is) 
{
    read(is);
    //foo();
    //bar();
    //baz();
}
Run Code Online (Sandbox Code Playgroud)

但是当你定义上面的两个构造函数时,你可以像使用类一样

std::istream is = std::cin;
Student_info si(is);
Run Code Online (Sandbox Code Playgroud)

OOP的主要目标之一是编写可重用而非自重的代码,另一个目标是分离关注点.在许多情况下,实例化对象的人不需要知道类的实现细节.

在你的示例read函数中,当调用其内部构造函数时,它可以是私有的 这为我们提供了另一个OOP 封装概念

最后,这不是双重工作,它是软件设计的好方法