【问题标题】:What is wrong with this constructor definition?这个构造函数定义有什么问题?
【发布时间】:2021-12-14 01:42:43
【问题描述】:

我想写一个“时钟”类,它基本上保存小时、分钟和秒(作为整数)。

我希望默认情况下,除非给出其他输入,否则构造函数会将小时、分钟和秒初始化为 0。所以我声明了以下内容:

    Clock(int hour=0, int minute=0, int second=0);

这基本上应该给我 4 个不同的构造函数 - 第一个是默认构造函数,然后是接收小时作为输入的构造函数,接收小时和分钟作为输入的构造函数,以及接收所有 3 的构造函数输入。

接下来,我希望构造函数仅在输入有效时才初始化字段,这意味着小时应该在 0 到 24 之间,分钟和秒应该在 0 到 60 之间。所以我写了 3 个函数来检查输入是否是合法的,然后我将构造函数实现如下:

Clock::Clock(int hour , int minute, int second ){
    if (isHourLegal(hour) && isMinLegal(minute) && isSecLegal(second)){
        time[0] = hour; time[1] = minute; time[2] =second;
    }
    else
        Clock();
}

其中time[] 是一个长度树数组,其中包含对象的小时、分钟和秒字段。

基本上,如果其中一个输入错误,我会调用Clock();,它应该使用我在声明时编写的默认干扰创建一个对象。

我实现构造函数的方式有问题吗?尝试打印对象字段时出现意外输出。

另外,

假设我将构造函数固定为:

Clock::Clock(int hour , int minute, int second ){
    if (isHourLegal(hour) && isMinLegal(minute) && isSecLegal(second)){
        time[0] = hour; time[1] = minute; time[2] =second;
    }
    else
        time[0] = 0; time[1] = 0; time[2] =0;
    }
}

我试图在我的主函数中调用默认构造函数:

Clock clock1();
clock1.printTime();

(printTime 是一种打印字段的方法)。

但是我得到一个错误。这样使用构造函数有问题吗?

【问题讨论】:

  • Clock(); 创建并丢弃一个新的临时对象。它不会影响已经构建的对象,因此您的成员变量将被取消初始化。
  • 只写Clock clock;。括号是不必要的,会混淆编译器。 Clock clock1(); 被解析为函数原型而不是变量定义。见:Most vexing parse
  • Clock clock1(); 应该是 Clock clock1;。带括号的是一个名为clock1 的函数的声明,它不接受任何参数并返回一个Clock 类型的对象。就像int f();
  • @andreee -- 基本规则是,如果它可以是函数声明,那么它就是函数声明。而且,是的,int f(); 满足该规则。但是“最令人烦恼的解析”这个词是为了描述更微妙的事情而发明的。维基百科页面上的第一个例子是void f(double my_dbl) { int i(int(my_dbl)); }。如果“最令人烦恼的解析”被如此广泛地阅读,以至于它适用于底层规则的每个应用程序,它就失去了它的意义。正如我之前所说,int f(); 在任何有意义的意义上都不是“烦恼”。这是声明不带参数的函数的方式。

标签: c++


【解决方案1】:

你可以轻松解决这个问题。

如果你有默认参数,那么这些参数很可能会通过测试(毕竟你定义了它们:-))。那么为什么不利用这一点,只编写一个处理这两种情况的构造函数呢?

在这两种情况下(即有/没有向其传递参数),都将执行检查,并在成功时构造一个有效的Clock。对于您的默认参数,这将是微不足道的。在失败的情况下,您的构造函数将抛出,并且您不会有一个半初始化/损坏的对象漫游。

也许您缺少的一点是:如果时间格式合法,you should usually throw

看看下面的定义,这对你的情况应该足够了。

// Declaration
Clock(int hour=0, int minute=0, int second=0);

// ...

// Definition
Clock::Clock(int hour, int minute, int second)
  : time { hour, minute, second } // assuming int time[3]; here
{
    if (!isHourLegal(hour) || !isMinLegal(minute) || !isSecLegal(second)){
        throw std::invalid_argument("Illegal time format!");
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-08
    • 2020-04-06
    • 1970-01-01
    • 2015-12-17
    相关资源
    最近更新 更多