修改std :: vector函数(继承?)

chr*_*244 3 c++ inheritance overloading operator-overloading c++11

我正在将一些Fortran90代码移植到C++中(因为我很愚蠢,为了保存"为什么?!").

Fortran允许在数组上指定范围,特别是从负值开始,例如

double precision :: NameOfArray(FirstSize, -3:3)
Run Code Online (Sandbox Code Playgroud)

我可以用C++编写这样的东西

std::array<std::array<double, 7>, FirstSize> NameOfArray;
Run Code Online (Sandbox Code Playgroud)

但现在我必须像索引一样NameOfArray[0:FirstSize-1][0:6].如果我想使用Fortran样式索引进行索引,我可以写一下

template <typename T, size_t N, int start>
class customArray
{
public:
    T& operator[](const int idx) { return data_[idx+start]; }
private:
    std::array<T,N> data_;
}
Run Code Online (Sandbox Code Playgroud)

然后

customArray<double, 7, -3> NameOfArray;
NameOfArray[-3] = 5.2;
NameOfArray[3] = 2.5;
NameOfArray[4] = 3.14; // This is out of bounds, 
                       // despite being a std::array of 7 elements
Run Code Online (Sandbox Code Playgroud)

所以 - 一般的想法是"不要在这里继承std ::'容器类'".我的理解是,这是因为,例如,std :: vector没有虚拟析构函数,因此不应该(不能?)以多态方式使用.

是否有一些其他的方式,我可以使用std::array,std::vector等等,并得到他们的职能"免费",同时覆盖特定的功能?

template<typename T, size_t N>
T& std::array<T,N>::operator[](const int idx) { ... };
Run Code Online (Sandbox Code Playgroud)

可能允许我覆盖运算符,但它不会让我访问有关自定义起点的知识 - 使它完全没有意义.另外,如果我乐观地认为我的所有customArray对象都具有相同的偏移量,我可以对该值进行硬编码 - 但是我的std :: array被破坏了(我认为).

我怎么能绕过这个?(忽略简单的答案 - 不要 - 只myArray[idx-3]需要根据需要写)

Eth*_*ris 6

继承标准容器没有问题.这通常是不鼓励的,因为这会产生一些限制,并且这种继承不是最初在C++中预测继承的方式.如果您小心并了解这些限制,则可以在此处安全地使用继承.

你只需要记住,这不是子类化,这实际上意味着什么.特别是,您不应该使用指针或对此类对象的引用.如果传递的值的问题可能是MyVector<x>*在那里vector<x>*进行了展望.你也不应该创建像动态(使用new)这样的对象,因此也可以delete通过指向基类的指针创建这些对象 - 因为析构函数调用不会转发到类的析构函数,因为它不是虚拟的.

不可能阻止将"派生指针"强制转换为"基指针",但是可以通过重载&运算符来防止从对象中获取指针.您还可以通过声明operator new私有部分中的类内(或= delete应该也可以)来动态地阻止创建此类的对象.

不要考虑私人继承.这仅仅是将此事件作为私有部分中的字段包含,除了访问者名称.

  • 我不同意第三和第四段.私有基类`class customArray:private std :: vector <float>`**do**防止转换为类的基类指针,但在类中(你知道要小心)你可以写`using`声明(你不能为成员做的事情) (2认同)