我经常遇到这样的问题,我想实现一个数据结构,并希望让用户扩展它的功能;那是向数据结构添加功能而不是字节。一个示例可以使用 sum 方法扩展 std::vector:
#include <iostream>
#include <vector>
// for the header file
template<>
int std::vector<int>::sum();
//for the object file
template<>
int std::vector<int>::sum() {
int s=0;
for(auto v = this->begin(); v!=this->end(); ++v) s+=*v;
return s;
}
int main() {
std::vector<int> numbers;
numbers.push_back(5);
numbers.push_back(2);
numbers.push_back(6);
numbers.push_back(9);
std::cout << numbers.sum() << std::endl;
return 0;
}
所以这是非法的,因为不能像这样向类中添加函数。显然这是 c++(11) 的一些设计决定。它可以通过两种方式规避,即定义一个
int sum(std::vector<int> &v) { ... }
这就是 std::sort 的工作方式,所以我猜这就是 c++(11) 的预期方式。据我所知,我认为这是用 C++ 实现的最佳方式。但是,它不允许我访问 std::vector 的私有(private)属性。也许我是邪恶的,因为我假设以一种(某种)方法访问私有(private)属性是公平的。但是,我经常希望我的类的用户不能访问某些内容,但是我希望允许我的扩展程序访问它们。例如,我可以想象 std::sort 可以针对 w.r.t 进行优化。特定的容器实现知识和访问权限。
另一种方法是继承 std::vector,但我发现由于以下原因,这显然是 Not Acceptable :
- 如果两方都用方法扩展了类,其中一方想使用哪一个,则需要从一个子类转换为另一个子类。这是荒谬的,因为一个人将数据转换为数据而不实际改变字节,因为两个子类(可以)具有完全相同的内存实现和分段。另请注意,数据转换通常是样板代码,恕我直言,样板代码应被视为邪恶。
- 一个是将功能与数据结构不必要地混合在一起,例如,类名 sum_vector 或 mean_vector 是完全的。
作为一个简短的提醒,我不是在寻找像“你不能在 c++ 中那样做”这样的答案,我已经知道了 ( Add a method to existing C++ class in other file )。 但是,我想知道是否有一个好的方法来进行功能类扩展。我应该如何管理访问私有(private)字段?为什么我想要私有(private)领域访问是不合理的?为什么我不能区分扩展程序和用户访问权限?
注意:可以说扩展程序需要 protected 访问权限,而用户需要公共(public)访问权限,但是,就像我说的那样,这将是扩展的继承方式,出于上述原因,我非常不喜欢它。
最佳答案
您永远不应该访问标准容器的私有(private)成员,因为它们不是其接口(interface)的一部分。
但是,您已经可以扩展标准容器的功能,如 std::vector
:即通过明智地使用迭代器和标准算法。
例如sum
功能由使用 std::的
begin()
和 end()
功能的非成员函数提供: vector
#include <algorithm>
#include <iterator>
#include <vector>
template<class Container, class Ret = decltype(*begin(c))>
Ret sum(Container const& c)
{
return std::accumulate(begin(c), end(c), Ret{});
}
关于c++ - 在声明后使用方法扩展类功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24106062/