私有init()成员函数的作用?Time类已有构造函数的场景疑问
疑问:Time类中私有init()函数的作用是什么?
这是一项学校作业,给定的Time类已预先定义了私有变量和init()函数。我需要声明并定义一个成员函数,将两个Time对象相加,并把结果保存到另一个类的Time成员变量中,但不确定该如何使用这个给定的init()函数。
给定的Time类代码
class Time { public: Time(); Time(int hours, int mins, int secs); // public member functions here friend std::ostream& operator << (std::ostream&, Time&); private: int theHour; int theMins; int theSecs; void init(int hours, int minutes, int seconds); };
我知道在创建Time对象并执行赋值操作前,需要检查小时、分钟、秒的值是否合法。原本我打算这样实现带参数的构造函数:
我计划的构造函数实现
Time::Time(int hours, int mins, int secs) { if ((hours < 0) || (mins < 0) || (secs < 0) || (hours > 60) || (mins > 60) || (secs > 60)) { cout << "Illegal time value.\n"; exit(1); } hours = theHour; mins = theMins; secs = theSecs; }
现在我困惑的是:既然这个构造函数已经能完成Time实例的初始化和非法值检查,那这个私有void init()函数的意义到底是什么?
回答
这个init()函数的核心作用是代码复用——把重复的初始化逻辑(合法性检查、成员变量赋值)抽出来,避免在多个地方写相同代码,同时保证逻辑一致性。
你看,Time类有两个构造函数:无参构造Time()和带参构造Time(int, int, int)。如果没有init(),你得在两个构造函数里分别写一遍合法性检查和赋值逻辑,不仅代码冗余,后续修改规则时还容易漏改。
举个正确的用法示例:
- 把合法性检查、变量赋值的逻辑全部放到
init()里:
void Time::init(int hours, int minutes, int seconds) { // 顺便纠正下:时间合法范围应该是小时0-23,分秒0-59,不是60 if ((hours < 0) || (minutes < 0) || (seconds < 0) || (hours > 23) || (minutes > 59) || (seconds > 59)) { std::cerr << "Illegal time value.\n"; exit(1); } // 你原来的构造函数赋值写反了,应该是成员变量接收参数值 theHour = hours; theMins = minutes; theSecs = seconds; }
- 然后在两个构造函数里直接调用
init():
// 无参构造,初始化默认时间00:00:00 Time::Time() { init(0, 0, 0); } // 带参构造,复用init的逻辑 Time::Time(int hours, int mins, int secs) { init(hours, mins, secs); }
另外,你需要实现的两个Time对象相加的函数,也能用到init()。比如把相加后的总秒数转换成时分秒,直接调用init()初始化结果对象,不用再重复写合法性检查:
// 假设声明一个成员函数add,返回相加后的Time对象 Time Time::add(const Time& other) const { int totalSecs = theHour*3600 + theMins*60 + theSecs; totalSecs += other.theHour*3600 + other.theMins*60 + other.theSecs; int hours = totalSecs / 3600; totalSecs %= 3600; int mins = totalSecs / 60; int secs = totalSecs % 60; Time result; result.init(hours, mins, secs); // 复用init的检查和赋值逻辑 return result; }
这样不管是构造函数还是其他需要初始化Time对象的场景,都能复用init()的逻辑,后续要调整合法性规则(比如支持超过24小时的累计时间),只需要修改init()一处即可。
内容的提问来源于stack exchange,提问作者Sonja Pleština
相关产品推荐
相关产品推荐

