我有这些课程:
class Base
{
...
private:
std::vector<X> v;
};
class Derived : public Base
{
Derived(X*, int n);
};
其中Derived的构造函数传递了一个项目X的数组,我需要将它插入到Base类中的vector v中。 (X是智能指针)
目前我看到两种方法:
我没有看到#2的任何优势,但是想知道#1是否是一个好的解决方案,或者是否有更好的方法来做到这一点。
谢谢!
答案 0 :(得分:5)
如果您可以修改Base
,则有第三个选项。您可以创建允许基类完全访问的向量protected
:
class Base
{
...
protected:
std::vector<X> v;
};
您的基类现在可以直接在v
上运行。如果您需要将大部分矢量功能暴露给Derived
,这是最简单的方法。
如果没有,我只想添加一个函数(即选项#1)并使其受到保护:
class Base
{
...
protected:
void push_back(const X &x)
{
v.push_back(x);
}
private:
std::vector<X> v;
};
答案 1 :(得分:4)
另一种选择是在base中创建一个(公共或受保护的)构造函数,它将获取参数并直接填充向量。不需要创建或传递中间向量。
class Base
{
. . .
protected:
Base(X* x,int n);
. . .
};
class Derived : public Base
{
Derived(X* xes, int n):Base(xes,n){};
};
答案 2 :(得分:1)
如果可以的话,我会在protected
中创建一个Base
构造函数,它接受X*
参数,就像Derived
构造函数一样,然后在Derived
中的构造函数初始化列表,将参数传递给Base
的受保护构造函数,并让它进行实际插入。
答案 3 :(得分:1)
如果希望基类中的容器保持私有,可以考虑在Base
中添加公共(或受保护)函数,以允许派生类添加范围。这样,可以封装Base
容器类型(Derived
不需要知道它是vector
),而Derived
仍然可以将整个内容传递到一个射击:
class Base
{
...
private:
std::vector<X> v;
protected
template <class iterator_t>
void assign( iterator_t first, iterator_t last) {
v.assign( first, last);
}
};
class Derived : public Base
{
Derived(X* p, int n) {
Base::assign( p, p+n);
}
};
这不是一个封装,但可以通过更改派生类来更改容器,并且可以轻松编写派生类,如果需要,可以采用不同于数组的形式获取数据。 as zdan suggested {{3}}此功能可以是Base
的公共或受保护构造函数的一部分,如果这更有意义(可能)。
使用迭代器范围来表示容器的内容或子集的想法在STL中很普遍。
答案 4 :(得分:0)
您应该将成员变量设置为protected
,以便继承Base
的类可以访问它。或者将成员变量保持为私有,但添加protected
访问器方法以允许继承base
的类添加到向量等