类中派生信息的成员函数[英] Member functions for derived information in a class

本文是小编为大家收集整理的关于类中派生信息的成员函数的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

在为类设计接口时,我通常会考虑是否应该提供可以通过使用其他成员函数的组合来计算/派生的成员函数.例如:

class DocContainer
{
 public:
   Doc* getDoc(int index) const;
   bool isDocSelected(Doc*) const;
   int getDocCount() const;

  //Should this method be here???
  //This method returns the selected documents in the contrainer (in selectedDocs_out)
  void getSelectedDocs(std::vector<Doc*>& selectedDocs_out) const;
};

我应该将它作为类成员函数提供还是作为命名空间提供,我可以在其中定义此方法?哪个更受欢迎?

推荐答案

一般来说,你应该更喜欢自由函数.从 OOP 的角度考虑.

如果函数不需要访问任何私有成员,那么为什么要给予访问它们?这不利于封装.这意味着当类的内部被修改时,更多的代码可能会失败.

它还限制了可能的代码重用量.

如果你把函数写成这样:

template <typename T>
bool getSelectedDocs(T& container, std::vector<Doc*>&);

然后,getSelectedDocs 的相同实现将适用于公开所需功能的任何类,而不仅仅是您的 DocContainer.

当然,如果您不喜欢模板,可以使用接口,然后它仍然适用于实现该接口的任何类.

另一方面,如果它是一个成员函数,那么它只适用于这个特定的类(可能还有派生类).

C++ 标准库遵循相同的方法.例如,考虑 std::find,正是因为这个原因,它才成为自由函数.它不需要知道它正在搜索的类的内部结构.它只需要满足其要求的 一些 实现.这意味着相同的 find() 实现可以在标准库或其他地方的任何容器上运行.

Scott Meyers 主张 同样的事情.

如果你不喜欢它弄乱你的主命名空间,你当然可以把它放到一个单独的命名空间中,为这个特定的类提供功能.

本文地址:https://www.itbaoku.cn/post/627317.html

问题描述

While designing an interface for a class I normally get caught in two minds whether should I provide member functions which can be calculated / derived by using combinations of other member functions. For example:

class DocContainer
{
 public:
   Doc* getDoc(int index) const;
   bool isDocSelected(Doc*) const;
   int getDocCount() const;

  //Should this method be here???
  //This method returns the selected documents in the contrainer (in selectedDocs_out)
  void getSelectedDocs(std::vector<Doc*>& selectedDocs_out) const;
};

Should I provide this as a class member function or probably a namespace where I can define this method? Which one is preferred?

推荐答案

In general, you should probably prefer free functions. Think about it from an OOP perspective.

If the function does not need access to any private members, then why should it be given access to them? That's not good for encapsulation. It means more code that may potentially fail when the internals of the class is modified.

It also limits the possible amount of code reuse.

If you wrote the function as something like this:

template <typename T>
bool getSelectedDocs(T& container, std::vector<Doc*>&);

Then the same implementation of getSelectedDocs will work for any class that exposes the required functions, not just your DocContainer.

Of course, if you don't like templates, an interface could be used, and then it'd still work for any class that implemented this interface.

On the other hand, if it is a member function, then it'll only work for this particular class (and possibly derived classes).

The C++ standard library follows the same approach. Consider std::find, for example, which is made a free function for this precise reason. It doesn't need to know the internals of the class it's searching in. It just needs some implementation that fulfills its requirements. Which means that the same find() implementation can work on any container, in the standard library or elsewhere.

Scott Meyers argues for the same thing.

If you don't like it cluttering up your main namespace, you can of course put it into a separate namespace with functionality for this particular class.