RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 745743
Accepted
Jens
Jens
Asked:2020-11-17 02:46:50 +0000 UTC2020-11-17 02:46:50 +0000 UTC 2020-11-17 02:46:50 +0000 UTC

复制和移动构造函数的“显式”

  • 772

是否有必要(如果需要,在什么情况下)将复制和移动构造函数指定为explicit?我在代码中看到了这一点,并不太明白。explicit帮助我们避免的不必要的隐式转换在哪里?

c++
  • 4 4 个回答
  • 10 Views

4 个回答

  • Voted
  1. Best Answer
    ixSci
    2020-11-17T14:47:28Z2020-11-17T14:47:28Z

    这个问题的答案很简单:在explicit需要的地方需要它,在不需要的地方,也不需要它。有一个常见的建议是,所有接受一个参数的构造函数都应该用 标记explicit,以避免在创建不明显的情况下意外创建类对象。例如,我们有一个函数void someFun(const std::shared_ptr<int[]>&),我们很偶然地像这样使用它:

    int* array = new int[55];
    someFun(array);
    delete[] array;
    

    如果没有构造函数std::shared_ptr,explicit那么代码将成功编译,在第三行我们将得到未定义的行为。但是由于 构造函数std::shared_ptr被标记,因为explicit我们不会偶然遇到这种情况。因此,它explicit旨在消除随机错误。

    至于explicit复制构造函数:我从来没有见过这样的东西,我想不出为什么需要它。如果我们想禁止复制,那么我们需要完全删除它,如果我们不想这样做,那么为什么只允许一组狭窄的句法选项来加入轮辐,使用它可以复制一个目的?

    一个例子是下面的代码:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class MeClass
    {
    public:
        MeClass(size_t idx, const string& tag = "") :
            m_Idx{idx},
            m_Tag{tag}
        {    
        }
        MeClass(const MeClass& rhs):
            m_Idx{rhs.m_Idx},
            m_Tag{rhs.m_Tag}
        {
        }
    private:
        size_t m_Idx;
        string m_Tag;
    };
    
    MeClass explicitReturn()
    {
        // Явный вызов конструктора 
        // Неявный вызов конструктора копирования
        // move нужен исключительно для исключения C++17 RVO
        return move(MeClass{2, "meTag"});
    }
    
    MeClass implicitReturn()
    {
        // Неявный вызов конструктора 
        // Неявный вызов конструктора копирования (до C++17)
        return {3, "meaTag"};
    }
    
    void funForFun(const MeClass& me)
    {
    
    }
    
    int main()
    {
        // Явный вызов конструктора
        MeClass me1{1};
        // Неявный вызов конструктора
        MeClass me2 = 2;
        // Неявный вызов конструктора копирования
        auto me3 = me1;
        // Явный вызов конструктора копирования
        auto me4{me1};
        // Неявный вызов конструктора
        funForFun(2);
        funForFun({3});
        // Явный вызов конструктора
        funForFun(me1);
    }; 
    

    如果您在代码中将构造函数标记为explicit,则指示其显式使用的示例将停止工作。复制构造函数也是如此。

    • 5
  2. Андрей Чивесон
    2020-11-17T04:00:56Z2020-11-17T04:00:56Z

    显式关键字将避免可能导致隐式错误的意外类型转换。

    例如:您有一个带有构造函数的类,该构造函数MyString(int size)创建一个大小为大小的字符串。还有一种方法print(const MyString&),当你调用时,print(3)你可以期待一个 print("3") 调用,但实际上你会得到一个 3 个字符的空字符串。

    可以在这里找到一个好的详细答案。

    • 0
  3. Andrey Burmagin
    2022-01-06T21:10:26Z2022-01-06T21:10:26Z

    将复制构造函数声明为explicit有助于避免错误地切片,尽管它不允许当前类型的所有按值传递参数。有关这方面的更多信息,请参见 Sutter 和 Alexandrescu 所著的“C++ 中的编程标准”一书的第 54 段。

    • 0
  4. Виталий
    2020-11-17T04:03:36Z2020-11-17T04:03:36Z

    如果您稍后定义或显式删除复制和移动运算符,则不需要这样做。

    • -1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5