c++ - 在声明后使用方法扩展类功能

标签 c++ function class c++11 methods

我经常遇到这样的问题,我想实现一个数据结构,并希望让用户扩展它的功能;那是向数据结构添加功能而不是字节。一个示例可以使用 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;
}

参见:http://ideone.com/YyWs5r

所以这是非法的,因为不能像这样向类中添加函数。显然这是 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/

相关文章:

python - 为什么(递归地)调用自身的成员方法不会进入无限循环?

php - 从 PHP 库中调用函数并显示查询结果

class - Swift 和使用类扩展

c# - 从当前方法 C# 向下调用方法 2 类

c++ - 如何修复已定义的类模板?

c++ - 制作和访问共享指针数组

c++ - 如何在 C++11 中将 lambda 表达式存储为类的字段?

python - 可以通过调用另一个函数来覆盖一个函数吗?

c++ - 在函数中将数组作为参数传递

c++ - 如何加快从流到内存的读取行?