我即将为我正在编写的库“创建”我自己的矢量类。我不会从头开始创建一个矢量类,但只需使用std::vector
作为父类,并将一些内容添加到我的派生矢量类中。
现在,说,我需要一些建议。我的问题是:
1)调用派生类vector
(当然是在另一个命名空间内)是不是一个坏主意?在这种情况下我会有什么样的冲突?
2)我想重载数学运算符,以便能够添加向量,按常量乘以向量等。这实际上是我决定在std::vector
之上构建向量类的原因。但是,我可以直接重载std::vector
的数学运算符,并省去了创建(又一个......)矢量类的麻烦 - 但这是一个坏主意吗?
3)我非常希望从std::vector
继承构造函数,但是在没有编译器错误的情况下完成这些操作会遇到很多麻烦。有人可以给我一个具体的例子,告诉我如何做到这一点?
谢谢!
答案 0 :(得分:3)
我会劝阻你这样做。如果您需要一个新容器,只需嵌入(或继承私有)std::vector<>
而不是公开继承它。
关于你的问题:
1)调用我的派生类向量(当然是在另一个命名空间内)是一个坏主意吗?在这种情况下我会有什么样的冲突?
只要您和您的任何客户都不会通过std
指令同时导入using
命名空间和命名空间,我就不会发现这方面的特殊问题。
2)我想重载数学运算符,以便能够添加向量,按常量乘以向量等。这实际上是我决定在std :: vector之上构建向量类的原因。但是,我可以直接重载std :: vector的数学运算符,并省去了创建(又一个......)矢量类的麻烦 - 但这是一个坏主意吗?
是的,这是一个坏主意。如果您为std::vector
创建了数学运算符的重载,则无法在std::vector
所属的命名空间中创建它们。通过ADL,即使不合适,也可能在该命名空间中找到全局operator +
。如果是这种情况,您的operator +
甚至不会被查找,并且您将收到编译器错误。
3)我非常想从std :: vector继承构造函数,但是在没有编译器错误的情况下完成这个操作会遇到很多麻烦。有人可以给我一个具体的例子,告诉我如何做到这一点?
在C ++ 11中,您可以使用继承的构造函数。例如:
#include <vector>
template<typename T, typename Allocator = std::allocator<T>>
class myvector : public std::vector<T, Allocator>
{
using typename std::vector<T, Allocator>::vector;
};
#include <iostream>
int main()
{
std::vector<int> vi { 1, 2, 3, 4, 5};
// Uses inherited constructor
myvector<int> v(vi.begin(), vi.end());
for (auto i : v) { std::cout << i << " "; };
}
以下是live example与GCC 4.8.0(beta)一起使用,它支持继承的构造函数。
答案 1 :(得分:2)
首先,请注意,如果您愿意,可以对您的继承进行模糊处理。使用private
继承,然后将vector
的所有函数与using
语句一起使用。因为vector
有很多内容,所以它仍然是一个相当大的类型,但它没有像明确委派每个函数那么多,它可以防止通常的继承异议,人们会不小心切片派生类和/或者在没有虚拟析构函数时使用错误的类型删除它。并非任何人都应该删除vector
。
1)使用命名空间std
中的相同名称本身并不是一个问题(毕竟这就是命名空间的用途),但有时可能会让读者感到困惑。他们可能只是假设你已经在某个地方完成了using std::vector;
。这是他们自己的错,但如果你能想到另一个合适的名字,那么惩罚你的读者的错误就没有任何好处。
2)您可以为标准类重载运算符,但不能在std
命名空间中重载。这就留下了一个问题,你应该重载它们的范围。通常你不想把东西放到头文件的全局范围内,但是你可以把它们放在一个名为{{的命名空间中。 1}}然后将vector_arithmetic
放入要使用它们的每个范围。仅仅因为你能做到并不意味着它是明智的 - 读者希望知道运算符可用于using namespace vector_arithmetic;
这样的常见类,并且更改可用运算符集可能会吓到并扰乱它们。
3)如果您没有C ++ 11构造函数继承,则无法继承构造函数。相反,您需要费力地编写自己的构造函数,这些构造函数采用正确的参数并在初始化列表中调用相应的基类构造函数。标准(或其他文档)将告诉您所需的所有构造函数签名。特别注意模板化的构造函数,注意构造函数在C ++ 03和C ++ 11中是不一样的。
最后,考虑编写一些免费函数:
vector
等等。如果操作员超载会引起混淆,那么它们通常是不值得的。
答案 2 :(得分:1)
1)在您的命名空间下编写您自己的向量。但是,尽量不要从STL中获得。
2,3)忘记std::vector
,编写自己的方法和操作符。
此外,您可以将std::vector
包装在新类中并编写接口来操作它。