C++ 利用值类型和引用的统一语法

C++ 利用值类型和引用的统一语法,c++,inheritance,design-patterns,C++,Inheritance,Design Patterns,假设我们有以下Base类和两个派生类Derived1和Derived2: class Base { // Some declarations ... }; class Derived1 : public Base { // Some declarations ... public: vector<int> _array; }; class Derived2 : public Base { // Some declarations ... public: vector<

假设我们有以下
Base
类和两个派生类
Derived1
Derived2

class Base {
// Some declarations ...
};

class Derived1 : public Base {
// Some declarations ...
public:
  vector<int> _array;
};

class Derived2 : public Base {
// Some declarations ...
public:
  vector<int> &_array;
};
Base
中使用名为
index
的纯虚拟函数是一种解决方案。但是,在这种情况下,我们需要在两个派生类中使用相同的
int-index(uint x){return_-array[x];}
实现。这很难看,我们无法在
Base
中实现该函数,因为它不知道
\u array

因此,我们必须(1)将
\u数组
的类型更改为相同的类型(例如,更改为
向量*
),并在
中实现
索引
,或者(2)在
派生1
派生
中实现两种实现,以便使用公共接口。但是,我负担不起(1),因为它会在
Derived1
中添加一个额外的间接层,如果可能的话,我希望避免这种情况。拥有大量这样的成员变量会让(2)变得可怕,因为这需要大量的样板文件和复制,而且很难维护

我知道这两个
索引
函数实际上是不同的函数
,因为它们在不同的类型上运行。在许多其他场景中,
Derived1
Derived2
需要单独的函数,因为它们具有不同的行为(并将编译为不同的目标代码)。然而,在C++的情况下,实现方式在语法上是相似的,所以我想知道是否有办法利用这个。 一种可能的解决方案是使用自由函数:

template <class T>
int index(const T &obj, uint x) {
  return obj._array[x];
}
模板
整数索引(常数T&obj,单位x){
返回对象数组[x];
}
在这里,我们宣布
index
Derived1
Derived2
的朋友。然而,这可能并不优雅,因为它使用了一个朋友声明(两次声明朋友也是重复的)

因此,我的问题是: 是否有更优雅的方法来实现
索引
,同时避免性能成本和代码重复

附录: CRTP与我想要的非常接近,但它在删除现有类型
Base
时引入了两个新类型(
Base
是第一个,而
Base
是第二个)。这样的重构会在代码库中引发更多的变化,这是不可取的(例如制作使用
Base
模板函数/类的函数/类,甚至将它们从头文件移动到源文件)。理想情况下,我想要的不需要对代码库的其余部分进行更改。

使用

模板
类别CrtpBase:公共B
{
公众:
int index(size_t ind){return static_cast(this)->_array[ind];}
};
结构Derived1:公共CrtpBase
{
向量_数组={1,2,3};
};
struct Derived2:公共CrtpBase
{
向量_arr={4,5,6};
向量和数组=\u arr;
};

.

我可以说您正在寻找一些设计模式吗?因为有一个标签[design patterns],这可能非常适合类
Base
。谢谢!然而,这完全删除了
Base
,但我想要的只是更改现有API的实现(为问题添加了更多的解释)。@loudandclear编辑的更改如何?您仍然可以保持
基本状态
CrtpBase
只允许您将此功能添加到
派生的
s中。哦,我明白了,不过缺少了一些功能。我认为CrtpBase应该是从B派生的,那么它就有意义了。是这样吗?
template <class T>
int index(const T &obj, uint x) {
  return obj._array[x];
}
template <typename D, typename B = Base>
class CrtpBase : public B
{
    public:
    int index(size_t ind){return static_cast<D*>(this)->_array[ind];}
};

struct Derived1 : public CrtpBase<Derived1>
{
    vector<int> _array = {1,2,3};
};

struct Derived2 : public CrtpBase<Derived2>
{
    vector<int> _arr = {4,5,6};
    vector<int>& _array = _arr;
};