【问题标题】:Implicit conversion to const of dynamically allocated arrays隐式转换为动态分配数组的 const
【发布时间】:2019-12-20 22:30:03
【问题描述】:

在下面的代码中,一个类拥有一个动态分配的数组。它通过一个隐式转换为const 的公共方法公开对该数组的只读访问。

#include <array>

template <class T, std::size_t N>
class A {
  const unsigned int size;
  std::array<T, N> *s;
public:
  A(const unsigned int _size, const std::array<T, N>& def) :
     size(_size),
     s(new std::array<T, N>[size])
  {
    for (unsigned int i = 0; i < size; i++)
      s[i] = def;
  }
  ~A() { delete[] s; }

  std::array<T, N> const* const conf() const { return s; }
};

int main()
{
  A a(10, std::array<int, 3>{0, 0, 0});
  auto x = a.conf();
  return 0;
}

A::conf() 中的隐式 const 转换是否会产生开销(例如通过调用 A::s 元素的复制构造函数)?

【问题讨论】:

  • 我认为您重新设计了代码,因为它是半封装的。您隐藏了内存管理,但没有隐藏您拥有数组的事实。至少,使用 std::vector 而不是 C 风格的数组,你会得到 size、迭代器等等。
  • 你的代码的另一个问题是它不遵循5的规则。例如A的复制构造会导致灾难。
  • @Phil1970 我同意,但添加所需的复制构造函数不会改变问题。

标签: c++ constants


【解决方案1】:

A::conf() 中的隐式 const 转换是否会产生开销(例如通过调用 A::s 元素的复制构造函数)?

没有

没有“overhead”,指针可以在其const-version 中隐式转换。通常,转换生成零汇编指令。


附加说明

经验证明

A::conf() 不调用任何复制构造函数。来自生成的程序集 (gcc -O3):

A<int, 3ul>::conf() const:
        movq    %rdi, %rax
        ret

如您所见,它只是返回指针而不产生任何进一步的指令。

注意:我在这里禁用了“内联优化”,否则整个函数将被优化,产生零开销。

小技巧

  • 可能有点离题,但最好避免在现代 C++ 中管理原始内存(尽可能)。 用std::vector怎么样?

  • 在签名std::array&lt;T, N&gt; const* const conf() const 中,第二个const 总是被编译器忽略。您可以省略使其更具可读性:std::array&lt;T, N&gt; const* conf() const

【讨论】:

  • 我会小心使用(优化的)程序集来“证明”事情。您必须对编译器隐藏正确的内容(例如这里的构造函数主体)或查看未优化的代码。即使那样,您也永远无法确定编译器错误(这当然是一个非常微不足道的案例)。不过,很好的答案!
  • 是的,你是对的。实际上,我也检查了未优化的程序集。当然,没有复制构造函数调用。但是,我没有报告它,因为未优化的汇编版本在这个简单的问题/答案的范围内太长了。我认为真正的问题是proof 的含义。证明引用实现(编译器)的东西是没有意义的。真正的证明只能以标准为主导。我将用更合适的标题更新该部分,谢谢。
【解决方案2】:

conf() 返回一个指针 (std::array&lt;T, N&gt; const*)。因此auto x = a.conf(); 将 x 的类型推导出为 const 指针std::array&lt;T, N&gt; const*。地址/指针按值复制(通常复制 4 字节/8 字节地址,具体取决于您的系统)。没有调用任何 c'tor。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 2016-06-27
    • 2020-07-20
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多