c++ - 如果我真的非常想从 STL 容器继承,并且我继承了构造函数并删除了 new 运算符,那会发生什么?

标签 c++ inheritance stl

假设我违背了我在本网站和其他在线网站上找到的所有建议,并做了这样的事情:

#include <vector>
#include <array>
#include <iostream>

using PointType = std::array<double, 3>;
class Point
:
    public PointType 
{
    public: 

        using PointType::PointType;

        Point(const Point& copy)
            :
                PointType(copy)
        {
            std::cout << "Point(const Point&)" << std::endl;
        }

        Point(Point&& rval)
            :
                PointType(rval)
        {
            std::cout << "Point(Point&&)" << std::endl;
        }

        // Prevent PolygonType* p = new Polygon; delete p;
        template<typename ...Args>
        void* operator new (size_t, Args...) = delete;
};

using PolygonType = std::vector<PointType>; 
class Polygon
:
    public PolygonType
{
    public: 

        using PolygonType::PolygonType;

        Polygon(const Polygon& copy)
            :
                PolygonType(copy)
        {
            std::cout << "Polygon(const Polygon&)" << std::endl;
        }

        Polygon(Polygon&& rval)
            :
                PolygonType(rval)
        {
            std::cout << "Polygon(Polygon&&)" << std::endl;
        }

        // Prevent PolygonType* p = new Polygon; delete p;
        template<typename ...Args>
        void* operator new (size_t, Args...) = delete;
};

如果我很高兴从不使用 newPointPolygon或类似类型,删除 new运算符负责处理未定义行为的问题:

std::array<double, 3> a = new Point({1., 2., 3.})
delete a; 

关于 std::vector<PointType> 的条件由在其上工作的算法强加的是相同的:算法检查公共(public)接口(interface)是否适合算法中所做的事情。如果我想要一个算法(函数模板)将这个点 vector 视为一个线段的开放链,或一个封闭的多边形,这就是一个问题。这不包括在解析函数模板候选时依赖隐式接口(interface)。此外,概念在到达时对我没有帮助,因为同样,容器上的条件相同,我希望算法对它们执行的操作不同。因此,另一方面,如果我执行标签分派(dispatch) with SFINAE using the new metafunctions from type_traits ,使用这样的具体类型并标记它们会使标签分派(dispatch)变得微不足道。检查模板参数是否已使用特定标记进行标记。

此外,随着 C++11 构造函数继承,重新键入构造函数的老问题也消失了。

因此,当以构造函数被继承的方式从 STL 继承时,仍然会发生爆炸,并且 new运营商被删除?一定有什么我没看到的。

最佳答案

如果您的对象将始终是静态或自动分配的(没有 new),那么它将以相同的方式被销毁,因此您不需要虚拟析构函数,所以这将按预期工作。

从标准容器中提取并没有被完全禁止,只是很危险。您似乎已经通过消除危险用例在很大程度上减轻了危险。

请注意,如果您确实允许动态分配然后通过指向基的指针删除,即使派生类没有自己的状态(即没有成员),您仍然会有 UB ).对象生命周期比仅计算数据成员要复杂得多。

您仍然可以允许动态分配并且永远不会通过指向基的指针进行删除,但是这在逻辑上是否适合您,更不用说是否具有足够的保护性,仅取决于上下文。 p>


轶事:我偶尔从“库代码”中的 vector/map 继承,不打算由其他任何人进一步扩展。它不是开源软件,它是我控制下的专有代码库,因此可以自由使用注释。如果要通过容器的整个界面,组合会有点痛苦。

关于c++ - 如果我真的非常想从 STL 容器继承,并且我继承了构造函数并删除了 new 运算符,那会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52890373/

相关文章:

c++ - 使用 C++11 共享库编译共享库(旧标准)

ORDER BY 在结构上的 C++ 实现

c++ - 如何 self 复制一个 vector ?

c++ - 管理由 `std::bind` 绑定(bind)的成员函数的生命周期

c++ - 如何将 CLion (1.2.4) 用于涉及 Qt Creator 的项目?

android - OpenGL ES 2.0 通过共享 C++ 代码在 ios 和 android 上进行抗锯齿或平滑处理

python - 如何测试从某个抽象类继承的对象类

c# - 如何在 C# 中创建类列表以在循环中迭代

xml - Moxy:对象列表 XML 和 JSON 不能同时看起来不错

c++ - 什么库包含 map STL 集合?