我应该如何对 C++ 类的成员进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/308581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:32:18  来源:igfitidea点击:

How should I order the members of a C++ class?

c++code-formatting

提问by Tommy Herbert

Is it better to have all the private members, then all the protected ones, then all the public ones? Or the reverse? Or should there be multiple private, protected and public labels so that the operations can be kept separate from the constructors and so on? What issues should I take into account when making this decision?

拥有所有私有成员,然后是所有受保护成员,然后是所有公共成员,是否更好?还是反过来?还是应该有多个私有、受保护和公共标签,以便操作可以与构造函数等分开?在做这个决定时,我应该考虑哪些问题?

回答by itsmatt

I put the public interface first, but I didn't always do this. I used to do things backwards to this, with private, then protected, then public. Looking back, it didn't make a lot of sense.

我把公共接口放在第一位,但我并不总是这样做。我过去常常这样做,先是私有的,然后是受保护的,然后是公共的。回想起来,没有太大的意义。

As a developer of a class, you'll likely be well acquainted with its "innards" but users of the class don't much care, or at least they shouldn't. They're mostly interested in what the class can do for them, right?

作为类的开发人员,您可能很熟悉它的“内部结构”,但类的用户并不在意,或者至少他们不应该在意。他们最感兴趣的是班级可以为他们做什么,对吧?

So I put the public first, and organize it typically by function/utility. I don't want them to have to wade through my interface to find all the methods related to X, I want them to see all that stuff together in an organized manner.

所以我把公众放在第一位,通常按功能/效用来组织它。我不希望他们不得不费力地通过我的界面来查找与 X 相关的所有方法,我希望他们以有组织的方式一起查看所有这些内容。

I never use multiple public/protected/private sections - too confusing to follow in my opinion.

我从不使用多个公共/受保护/私人部分 - 在我看来太混乱了。

回答by Josh Kelley

Google favors this order: "Typedefs and Enums, Constants, Constructors, Destructor, Methods, including static methods, Data Members, including static data members."

Google 赞成这样的顺序:“Typedefs 和 Enums、Constants、Constructors、Destructor、Methods,包括静态方法,Data Members,包括静态数据成员。”

Matthew Wilson(Safari subscription required) recommends the following order: "Construction, Operations, Attributes, Iteration, State, Implementation, Members, and my favorite, Not to be implemented."

Matthew Wilson(需要 Safari 订阅)推荐以下顺序:“构造、操作、属性、迭代、状态、实现、成员和我最喜欢的,不要被实现。”

They offer good reasons, and this kind of approach seems to be fairly standard, but whatever you do, be consistent about it.

他们提供了很好的理由,这种方法似乎相当标准,但无论你做什么,都要保持一致。

回答by korona

It's my opinion, and I would wager a guess that most people would agree, that public methods should go first. One of the core principles of OO is that you shouldn't have to care about implementation. Just looking at the public methods should tell you everything you need to know to use the class.

这是我的观点,我敢打赌大多数人都会同意,公共方法应该先行。OO 的核心原则之一是您不必关心实现。只需查看公共方法就可以告诉您使用该类需要知道的一切。

回答by MattyT

As always, write your code for humans first. Consider the person who will be using your class and place the most important members/enums/typedefs/whatever to themat the top.

与往常一样,首先人类编写代码。考虑将使用您的类的人,并将最重要的成员/枚举/类型定义/对他们而言的任何内容放在顶部。

Usuallythis means that public members are at the top since that's what most consumers of your class are most interested in. Protected comes next followed by privates. Usually.

通常这意味着公共成员位于顶部,因为这是您班级的大多数消费者最感兴趣的。受保护的紧随其后的是私有成员。通常。

There are some exceptions.

有一些例外。

Occasionally initialisation order is important and sometimes a private will need to be declared before a public. Sometimes it's more important for a class to be inherited and extended in which case the protected members may be placed higher up. And when hacking unit tests onto legacy code sometimes it's just easier to expose public methods - if I have to commit this near-sin I'll place these at the bottom of the class definition.

有时初始化顺序很重要,有时需要在公共之前声明私有。有时,继承和扩展类更重要,在这种情况下,受保护的成员可能会放在更高的位置。当对遗留代码进行单元测试时,有时公开公共方法会更容易 - 如果我必须提交这种近乎罪过的行为,我会将它们放在类定义的底部。

But they're relatively rare situations.

但它们是相对罕见的情况。

I find that most of the time "public, protected, private" is the most useful to consumers of your class. It's a decent basic rule to stick by.

我发现大部分时间“公共、受保护、私有”对您班级的消费者最有用。坚持是一个体面的基本规则。

But it's less about ordering by access and more about ordering by interest to the consumer.

但这不是按访问订购,而是按消费者的兴趣订购

回答by PolarBear2015

Coding style is a source for surprisingly heated conversation, with that in mind I risk providing a different opinion:

编码风格是令人惊讶的激烈对话的来源,考虑到这一点,我冒着提供不同意见的风险:

Code should be written so it is most readable for humans. I complete agree with this statement that was given here several times.

代码应该写成对人类最易读。我完全同意这里多次给出的声明。

The deviation is which roll are we taking about.

偏差是我们采取的滚动方式。

To help the userof the class understand how to use it, one should write and maintain proper documentation. A user should never be needing to read the source code to be able to use the class. If this is done (either manually or using in-source documentation tools) then the order in which public and private class members are defined in the source does not matter for the user.

为了帮助类的用户了解如何使用它,应该编写和维护适当的文档。用户永远不需要阅读源代码即可使用该类。如果这样做(手动或使用源内文档工具),那么公共和私有类成员在源中定义的顺序对用户来说无关紧要。

However, for someone who needs to understandthe code, during code review, pull request, or maintenance, the order matters a great deal - the rule is simple:

然而,对于需要理解代码的人来说,在代码、拉取请求或维护期间,顺序很重要——规则很简单:

items should be defined before they are used

项目应该在使用之前定义

This is neither a compiler rule not is it a strictly public v.s. private rule, but common sense - human readability rule. We read code sequentially, and if we need "juggle" back and forth every time we see a class member used, but don't know its type for example, it adversely affects the readability of the code.

这既不是编译器规则,也不是严格的公共与私有规则,而是常识 - 人类可读性规则。我们按顺序阅读代码,如果我们每次看到使用的类成员时都需要来回“玩弄”,但不知道它的类型,例如,它会对代码的可读性产生不利影响。

Making a division strictly on private v.s. public violates this rule because private class members will appear after they have been used in any public method.

严格区分 private 和 public 违反了这条规则,因为私有类成员在任何公共方法中使用后都会出现。

回答by David Rodríguez - dribeas

I usually define first the interface (to be read), that is public, then protected, then private stuff. Now, in many cases I go a step forward and (if I can handle it) use the PIMPL pattern, fully hiding all the private stuff from the interface of the real class.

我通常首先定义接口(要读取),即公共的,然后是受保护的,然后是私有的。现在,在许多情况下,我向前迈进了一步,(如果我能处理的话)使用 PIMPL 模式,从真实类的接口中完全隐藏所有私有内容。

class Example1 {
public:
   void publicOperation();
private:
   void privateOperation1_();
   void privateOperation2_();

   Type1 data1_;
   Type2 data2_;
};
// example 2 header:
class Example2 {
   class Impl;
public:
   void publicOperation();
private:
   std::auto_ptr<Example2Impl> impl_;
};
// example2 cpp:
class Example2::Impl
{
public:
   void privateOperation1();
   void privateOperation2();
private: // or public if Example2 needs access, or private + friendship:
   Type1 data1_;
   Type2 data2_;
};

You can notice that I postfix private (and also protected) members with an underscore. The PIMPL version has an internal class for which the outside world does not even see the operations. This keeps the class interface completely clean: only real interface is exposed. No need to argue about order.

您会注意到我用下划线对私有(也受保护)成员进行了后缀。PIMPL 版本有一个内部类,外部世界甚至看不到它的操作。这使类接口完全干净:只暴露真正的接口。无需争论秩序。

There is an associated cost during the class construction as a dynamically allocated object must be built. Also this works really well for classes that are not meant to be extended, but has some short comings with hierarchies. Protected methods must be part of the external class, so you cannot really push them into the internal class.

在类构建期间存在相关成本,因为必须构建动态分配的对象。此外,这对于不打算扩展的类非常有效,但有一些层次结构的缺点。受保护的方法必须是外部类的一部分,因此您不能真正将它们推入内部类。

回答by ayaz

I tend to follow the POCO C++ Coding Style Guide.

我倾向于遵循POCO C++ Coding Style Guide

回答by Dan Olson

In practice, it rarely matters. It's primarily a matter of personal preference.

在实践中,这很少重要。这主要是个人喜好的问题。

It's very popular to put public methods first, ostensibly so that users of the class will be able to find them more easily. But headers should never be your primary source of documentation, so basing "best practices" around the idea that users will be looking at your headers seems to miss the mark for me.

将公共方法放在首位是非常流行的,表面上是为了让类的用户能够更容易地找到它们。但是标题永远不应该是您文档的主要来源,因此围绕用户将查看您的标题的想法建立“最佳实践”似乎对我来说没有把握。

It's more likely for people to be in your headers if they're modifyingthe class, in which case they shouldcare about the private interface.

如果人们正在修改类,他们更有可能出现在您的标题中,在这种情况下,他们应该关心私有接口。

Whichever you choose, make your headers clean and easy to read. Being able to easily find whatever info I happen to be looking for, whether I'm a user of the class or a maintainer of the class, is the most important thing.

无论您选择哪种方式,都要使标题干净且易于阅读。能够轻松找到我碰巧正在寻找的任何信息,无论我是类的用户还是类的维护者,都是最重要的事情。

回答by Dave Van den Eynde

In our project, we don't order the members according to access, but by usage. And by that I mean, we order the members as they are used. If a public member uses a private member in the same class, that private member is usually located in front of the public member somewhere, as in the following (simplistic) example:

在我们的项目中,我们不是根据访问权限对成员进行排序,而是根据使用情况进行排序。我的意思是,我们按照成员的使用情况对成员进行排序。如果公共成员使用同一类中的私有成员,则该私有成员通常位于公共成员的前面某处,如下面(简单的)示例所示:

class Foo
{
private:
  int bar;

public:
  int GetBar() const
  {
    return bar;
  }
};

Here, the member baris placed before the member GetBar()because the former is used by the latter. This can result in multiple access sections, as in the following example:

在这里,成员被放置在成员GetBar()之前,因为前者被后者使用。这可能会导致多个访问部分,如下例所示:

class Foo
{
public:
  typedef int bar_type;

private:
  bar_type bar;

public:
  bar_type GetBar() const
  {
    return bar;
  }
};

The bar_typemember is used by the barmember, see?

bar_type件所用的件,看到了吗?

Why is this? I dunno, it seemed more natural that if you encounter a member somewhere in the implementation and you need more details about that (and IntelliSense is screwed up again) that you can find it somewhere above from where you're working.

为什么是这样?我不知道,如果您在实现中的某个地方遇到一个成员并且您需要更多关于它的详细信息(并且 IntelliSense 又被搞砸了),您可以在您工作的地方上方的某个地方找到它,这似乎更自然。

回答by unwind

i think it's all about readability.

我认为这都是关于可读性的。

Some people like to group them in a fixed order, so that whenever you open a class declaration, you quickly know where to look for e.g. the public data members.

有些人喜欢将它们按固定顺序分组,这样无论何时打开类声明,您都可以很快知道在哪里查找,例如公共数据成员。

In general, I feel that the most important things should come first. For 99.6% of all classes, roughly, that means the public methods, and especially the constructor. Then comes public data members, if any (remember: encapsulation is a good idea), followed by any protected and/or private methods and data members.

总的来说,我觉得最重要的事情应该放在第一位。对于 99.6% 的类,粗略地说,这意味着公共方法,尤其是构造函数。然后是公共数据成员,如果有的话(记住:封装是个好主意),然后是任何受保护和/或私有方法和数据成员。

This is stuff that might be covered by the coding standards of large projects, it can be a good idea to check.

这是大型项目的编码标准可能涵盖的内容,检查一下可能是个好主意。