【问题标题】:C++ function = deleteC++ 函数 = 删除
【发布时间】:2015-10-16 15:17:30
【问题描述】:

在 C++ 中(我相信自 C++ 11 起),只要程序员不希望编译器自动实现默认构造函数或赋值运算符,就可以“删除”构造函数或赋值运算符。

例如,一个可能,

class a
{
    const a& operator=(const a& copy_me) = delete;
}

这将删除默认的赋值运算符。编译器不会为我们实现默认的operator=。我们根本无法在我们的代码中使用它,就好像它从未存在过一样。

考虑一个包含函数、虚函数和纯虚的抽象基类(或只是一个基类)。

class example_base
{
    void function()
    {
        return;
    }

    virtual
    void virtual_function() // Do we have to provide an implementation?
    {
        return;
    }

    virtual
    void pure() = 0; // Are there other ways to declare a pure virtual?
                     // Can pure() have an implementation in this class?
}

如果另一个类继承自基类,我们是否允许“删除”基类中提供的某些功能? (第一季度)

如果是这样,它的规则和效果是什么? (第二季度)

如果后续的类继承自example_inherits,而我们删除了一些成员函数会怎样?我们可以再次使用它们吗? (第三季度)

class example_inherits : example_base
{
    void function() = delete; // Allowed?

    virtual
    void virtual_function() = delete; // If so why ...

    virtual
    void pure() = delete; // ... or why not?
}

Q3 示例:

class another : example_inherits
{
    // Allowed to use deleted function?
    void function()
    {
        std::cout << "blaa" << std::endl;
    }
}

您可能会想到我所描述的其他排列,例如实现一个已删除的方法 2 继承顺序较低。 (即,在从类继承的类中继承的类中......)

或者虚拟/纯虚拟顺序的不同选择...例如:一个类有一个虚拟纯,某些东西从这个类继承并继承与虚拟相同的功能,然后从这个继承的另一个类要么删除它,要么实现它作为一个常规功能......等等......

我们将不胜感激 - 我无法在网上找到如此详细的信息。

【问题讨论】:

  • @MattMcNabb 2个不同的案例有什么效果?

标签: c++ class oop inheritance polymorphism


【解决方案1】:

Matt 的回答几乎涵盖了所有内容,但我可以回答为什么不能删除虚函数的问题(Q3):

虚函数的全部意义在于启用subtype polymorphism。对此的合理实现意味着您可以在使用基类型编写的任何合法实现的函数中使用任何合法实现的子类型。这是Liskov Substitution Principle 的改写。

这意味着如果您能够删除子类中的虚函数,则该子类在用于合法实现的函数时会产生未定义的行为。不完全是可取的,我也无法想象它会带来任何好处的情况。

【讨论】:

    【解决方案2】:

    嗯,你有很多问题在这里。他们都可以通过尝试得到答案:)

    我们根本无法在我们的代码中使用它,就好像它从未存在过一样

    不完全是,因为删除的版本参与了重载决议。例如:

    void f(long);
    void f(int) = delete;
    
    f(5);
    

    这将无法编译,但是如果您注释掉 =delete 版本,则它会编译。


    继续您的问题。

    pure() 可以在这个类中实现吗?

    是的,= 0 仅表示派生类必须覆盖它。但是您仍然可以在同一个类中为该函数提供一个离线定义。

    void function() = delete; // Allowed?

    是的,这是允许的。派生的function() 隐藏了基础function(),因为它不是虚拟的。当然,您仍然可以通过指针或对基类的引用来调用基类 function

    void virtual_function() = delete;

    这是不允许的;虚函数不能被删除。

    【讨论】:

    • 好的,谢谢 - 我认为纯虚拟也可能不会被删除。这是有原因的 - 还是它就是这样?
    • 纯虚拟是虚拟的一个子集。我不知道官方原因,但正如我们从您的问题中看到的那样,如果允许的话,它看起来会变成一罐蠕虫。
    • 里氏替换原则。派生类必须至少能做与基类一样多的事情。
    猜你喜欢
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 2011-04-24
    相关资源
    最近更新 更多