【问题标题】:Overloading explicit constructor in C++在 C++ 中重载显式构造函数
【发布时间】:2018-06-11 05:20:02
【问题描述】:

我正在读一本书,得到了一些我不太了解的类设计代码。

class Queue {
public:
    Queue(size_t capacity) {}
    explicit Queue(int capacity) : entries_(capacity) {}
...
private:
    vector<int> entries_;
...
};

还有一个类似的,

class LruCache {
public:
    LruCache(size_t capacity) {}
    explicit LruCache(int capacity) : capacity_(capacity) {}
...
private:
    int capacity_;
...
};

我有两个问题,

  1. 我们能否仅在 explicit 关键字上重载方法,例如 const 关键字?就我而言,参数类型有点不同,intsize_t

  2. 一个更重要的问题是为什么。为什么我们需要一个重载的explicit 构造函数?在 C++ 入门中,我相信它说不建议重载具有相似参数类型的函数。

编辑:

我的第二个问题更多关于上面的代码。为什么它有一个带有int 参数的构造函数,然后是一个带有size_t 参数的explicit 构造函数,而intsize_t 是非常接近的类型。因此,不必为每个构造函数定义两个构造函数。我相信作者定义两个构造函数是有原因的,但我不知道为什么,这应该是我的第二个问题。不是关于 explicit 关键字做什么的一般问题。对不起。

【问题讨论】:

  • intsize_t 是不同的类型。代码不是“显式重载”,而是在size_tint 上重载;如果在不允许的地方选择了显式构造函数,则代码格式错误
  • explicit 不是函数签名的一部分,因此函数不能被它重载。
  • 这本书有没有讲为什么它有这些构造函数?仅基于发布的内容,这对我来说似乎是一个糟糕的主意。
  • 1.不; 2.显式与重载无关,它只是防止给定的ctor被考虑进行自动转换;只影响一个参数的ctors
  • @C.M. - 自 C++11 起影响更大。 stackoverflow.com/questions/39122101/…

标签: c++ oop constructor overloading explicit


【解决方案1】:

我们能否仅在 explicit 关键字上重载方法

没有。

为什么我们需要重载的显式构造函数?

为了避免隐式转换。

假设Queue 被定义为:

class Queue {
  public:
    // No constructor with a size_t.
    Queue(int capacity) {}
  ...
};

这样,int 将在需要时隐式转换为 Queue

void bar(Queue const& q) { ... }

bar(10); // This would be valid without the explicit keyword.
         // 10 will be implicitly converted to Queue(10).

有时这种隐式转换会导致代码难以理解和维护。 explicit 限定符用于避免此类隐式转换。

使用 explicit 限定符,您将需要使用

bar(Queue(10));

这更容易理解。

为什么它有一个带有size_t 参数的构造函数,然后是一个带有int 参数的explicit 构造函数,

我看不出有什么理由需要这两个重载——explicit 或不需要。如果这本书没有解释为什么需要它们,我们只能将其归咎于作者不够清晰。

【讨论】:

  • bar(10) 在现有代码中是有效的,因为选择了非显式 size_t 构造函数。 (与现有构造函数有不同的语义)
  • 这不应该是真的。 “10”不应具有 size_t 类型。 bar(10z) 或 bar((size_t)10) 可以选择 Queue(size_t) 构造函数。
猜你喜欢
  • 2012-12-23
  • 2011-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多