tma*_*ric 3 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;
};
Run Code Online (Sandbox Code Playgroud)
如果我很高兴与从不使用新的与Point或Polygon或相似类型的删除new操作需要照顾的未定义行为的问题:
std::array<double, 3> a = new Point({1., 2., 3.})
delete a;
Run Code Online (Sandbox Code Playgroud)
std::vector<PointType>对其起作用的算法施加的条件是相同的:算法检查公共接口是否适合算法中的操作.如果我想要一个算法(函数模板)来查看这个点向量作为线段的开链或闭合多边形,这是一个问题.这解析了在解析函数模板候选时依赖于隐式接口.此外,概念在它们到达时对我没有帮助,因为同样,容器上的条件是相同的,我希望算法对它们做的不同.因此,如果我使用新的元函数type_traits执行使用SFINAE的标签调度来检查模板参数是否已使用特定标记进行标记,那么使用这样的具体类型并标记它们会使标签调度变得微不足道.
此外,重新键入构造函数的旧问题也随着C++ 11构造函数继承而消失.
那么,当继承STL并继承构造函数并new删除运算符时,仍会爆炸的是什么?必须有一些我没有看到的东西.
如果您的对象将始终静态或自动分配(否new),那么它将以相同的方式被破坏,因此您不需要虚拟析构函数,因此这将按预期工作.
从标准容器中获取并非完全禁止,这只是危险的.通过消除危险的用例,您似乎在很大程度上减轻了危险.
请注意,如果您确实允许动态分配然后通过指向基类的删除,即使派生类没有自己的状态(即没有成员),您仍然有UB.对象生命周期比仅计算数据成员要复杂得多.
您仍然可以允许动态分配,并且永远不会通过指向基础的指针进行删除,但是这在逻辑上是否适合您,更不用说足够的保护性,仅取决于上下文.
轶事:我也偶尔从矢量/图继承了"库中的代码"不希望被任何其他人进一步扩大.它不是开源软件,它是我控制下的专有代码库,所以通过自由使用评论就可以了.如果要通过容器的整个界面,组合会有点痛苦.
| 归档时间: |
|
| 查看次数: |
108 次 |
| 最近记录: |