Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
扩展C++;继承的标准库? 通常认为C++标准库一般不打算使用继承来扩展。当然,我(和其他人)批评了那些建议从类派生的人,比如std::vector。然而,这个问题:让我意识到标准库中至少有一部分打算进行如此扩展-std::exception_C++_Stl - Fatal编程技术网

扩展C++;继承的标准库? 通常认为C++标准库一般不打算使用继承来扩展。当然,我(和其他人)批评了那些建议从类派生的人,比如std::vector。然而,这个问题:让我意识到标准库中至少有一部分打算进行如此扩展-std::exception

扩展C++;继承的标准库? 通常认为C++标准库一般不打算使用继承来扩展。当然,我(和其他人)批评了那些建议从类派生的人,比如std::vector。然而,这个问题:让我意识到标准库中至少有一部分打算进行如此扩展-std::exception,c++,stl,C++,Stl,因此,我的问题分为两部分: 是否有任何其他标准库类打算从中派生 如果从标准库类(如std::exception)派生,是否受ISO标准中描述的接口约束?例如,使用异常类的程序what()成员函数没有返回NTB(比如返回空指针)是否符合标准 a) 流库被设置为继承:)回答问题2): 我相信是的,他们将受到ISO标准接口描述的约束。例如,该标准允许全局重新定义运算符new和运算符delete。但是,该标准保证运算符delete在空指针上是一个no操作 不尊重这一点肯定是未定义的行为(至少对Scott

因此,我的问题分为两部分:

  • 是否有任何其他标准库类打算从中派生

  • 如果从标准库类(如
    std::exception
    )派生,是否受ISO标准中描述的接口约束?例如,使用异常类的程序
    what()
    成员函数没有返回NTB(比如返回空指针)是否符合标准

  • a) 流库被设置为继承:)

    回答问题2):

    我相信是的,他们将受到ISO标准接口描述的约束。例如,该标准允许全局重新定义
    运算符new
    运算符delete
    。但是,该标准保证
    运算符delete
    在空指针上是一个no操作


    不尊重这一点肯定是未定义的行为(至少对Scott Myers而言)。我想我们可以说,类比标准库的其他领域也是如此。

    对于第二个问题,我相信答案是肯定的。标准规定std::exception的what成员必须返回非NULL值。我是否有std::exception的堆栈、引用或指针值并不重要。what()的返回受标准约束


    当然可以返回NULL。但是,我认为这样的类是非标准符合的。

    < <代码>函数中的一些东西,如<代码>更大的< /代码>,<>代码> < >和<>代码> Mimu-Funtht >源于<代码> unyalx运算符< /COD>和<代码> Bialyx运算符< /C>。但是,IIRC,这只会给你一些类型定义。

    好问题。我真的希望标准能更明确地说明预期用途。也许应该有一个C++语言文档,它与语言标准并驾齐驱。在任何情况下,以下是我使用的方法:

    (a) 我不知道有这样的名单。相反,我使用以下列表来确定标准库类型是否可能被设计为继承自:

    • 如果它没有任何
      virtual
      方法,那么您不应该将其用作基础。这排除了
      std::vector
    • 如果它确实有
      virtual
      方法,那么它可以作为基类使用
    • 如果有大量的
      friend
      语句浮动,那么请避开,因为可能存在封装问题
    • 如果它是一个模板,那么在继承它之前请仔细查看,因为您可能可以使用专门化来定制它
    • 基于策略的机制(例如,
      std::char_traits
      )的存在是一个很好的线索,说明您不应该将其用作基础
    不幸的是,我不知道一个好的综合或黑白名单。我通常凭直觉行事


    (b) 我会在这里申请。如果有人对您的异常调用
    what()
    ,那么它的可观察行为应该与
    std::exception
    的行为相匹配。我不认为这是一个标准一致性问题,而是一个正确性问题。该标准不要求子类可以替代基类。它实际上只是一个“最佳实践”。

    < P> C++标准库不是单一的单元。它是组合和采用几个不同库的结果(C标准库的很大一部分、iostreams库和STL是三个主要的构建块,并且每一个都是独立指定的)

    正如您所知,库的STL部分通常不是从中派生的。它使用泛型编程,通常避免面向对象编程

    IOStreams库是更传统的面向对象编程,在内部大量使用继承和动态多态性,用户希望使用相同的机制来扩展它。自定义流通常通过从stream类本身或其内部使用的
    streambuf
    类派生来编写。这两种方法都有可以在派生类中重写的虚拟方法

    std::exception
    是另一个例子

    正如D.Shawley所说的,我将把这个问题应用到你的第二个问题上。用基类替换派生类应该是合法的。如果我调用
    exception::what()
    ,它必须遵循
    exception
    类指定的约定,无论
    exception
    对象来自何处,或者它是否实际上是一个已被升级的派生类。在这种情况下,该合同是标准公司关于返还非关税壁垒的承诺。如果你让一个派生类的行为不同,那么你会违反标准,因为一个类型的对象<代码> STD::异常< /代码>不再返回NTBS.< /P> < P> W.R.T问题2),根据C++标准,派生异常类必须指定一个“不抛出”即“丢())规范以及返回非空。这意味着在许多情况下,派生异常类不应使用std::string,因为std::string本身可能会根据实现而抛出。

    节约规则是“任何类别都可以用作基类;在没有虚拟方法(包括虚拟析构函数)的情况下安全使用它的责任完全由派生作者承担。“在std::exception的子类中添加非POD成员与在std::vector的派生类中添加非POD成员是相同的用户错误
    class CfgValue : public std::string {
    public:
        ...
        CfgValue( const int i ) : std::string() { SetInteger(i); }
        ...
        void SetInteger( int i );
        ...
        int GetInteger() const;
        ...
        operator std::wstring() { return utf8_to_ucs16(*this); }
        operator std::wstring() const { return utf8_to_ucs16(*this); }
        ...
    };