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

16

93

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?

Mick answered 21/11, 2008 at 12:13 Comment(5)
It's interesting to see how such nearly entirely opinion-based threads were warmly received 'back in the day', whereas I presume and rather hope they would be flagged into oblivion nowadays.Ellinger
I'm inclined to agree with this now, but I'm hesitating to delete it because it's been quite popular.Mick
@Ellinger I really wonder why, many many questions, few words that don't have any details or clarity, completely opinion based have 700 upvotes. Whereas the same question today would get 3-4 downvotes and closed immediately within secondsMaretz
Progress I guess?Mick
It's a question that all C++ programmers will ask themselves at some point. And it's not clear that the answer is that 'it's opinion-based'. I think such questions should be allowed to live, as long as the tone is kept civil, and as long as there are still subtle points to be made, for instance about readability or maintainability.Brownstone
K
65

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.

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

Kinna answered 21/11, 2008 at 12:30 Comment(4)
This is only my opinion, but I don't agree that the users of a class shouldn't care about the innards. I think the users should care, because the abstraction and encapsulation is there only to allow complex problems to be tackled and not to free the users of having to deal with the details.Loggia
Appreciate the comment, Dave. If I'm evaluating the efficiency or the "how" of a class or if I'm concerned that it isn't correct, then I'm going to care about the innards, but mostly as a user of the class, I'm concerned about the behavior of the class, not how it manages things internally.Kinna
@Kinna sizeof(object) depends on the order of the members if I am not mistaken. If so does it not have impact on the order? Suppose I have one double in private as well as public and then other char type variables, do I need to place double variables together? In such case how do we handle?Floor
This is completely opinion based with arguments for both sides. Starting with private allows one to build-up from hidden data members to what clients of the class can do - kind of logical order. Starting with public allows someone reading the class to immediately see its public interface and stop reading as soon as the public section ends - kind of order easier for the reader.Yawning
L
48

Google favors this order: "Typedefs and Enums, Constants, Constructors, Destructor, Methods, including static methods, Data Members, including static 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."

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

Labarum answered 21/11, 2008 at 12:35 Comment(0)
C
12

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 user of 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 understand the 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.

Carriecarrier answered 6/5, 2017 at 20:8 Comment(2)
If I could I would give more than just this one vote I'm allowed to give. I could not have said it better myself. Use your IDEs "Structure" tab or the documentation if you want to consume, if you need to actually review/understand the code this as presented here makes the most sense.Lampkin
I agree: providing documentation / interfaces for the user and on the other hand structure the code for the programmer is the right way. I prefer declaring my private members (properties) first and then define the operations (methods) the class/object uses to alter them.Braley
E
9

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.

Equitation answered 21/11, 2008 at 12:19 Comment(1)
IMO, OOP principles does not have to do with where you write your public members.Archbishopric
A
6

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 them at the top.

Usually this 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.

Acrobatics answered 21/11, 2008 at 13:29 Comment(0)
V
4

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.

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.

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.

Virtu answered 21/11, 2008 at 12:54 Comment(0)
K
4

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

Koral answered 21/11, 2008 at 13:26 Comment(1)
see 6.1 rule 36 (for order between public, protected, private). Unfortunately, it doesn't precise where static variables should be put.Evanish
L
3

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 bar is 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:

class Foo
{
public:
  typedef int bar_type;

private:
  bar_type bar;

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

The bar_type member is used by the bar member, see?

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.

Loggia answered 21/11, 2008 at 13:5 Comment(0)
D
2

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.

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

Donnelldonnelly answered 21/11, 2008 at 12:21 Comment(0)
L
2

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 modifying the class, in which case they should care 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.

Lignify answered 16/3, 2009 at 9:54 Comment(0)
S
2

Put the private fields first.

With modern IDEs, people don't read the class to figure out what it's public interface is.

They just use intellisence (or a class browser) for that.

If someone is reading through the class definition, it's usually because they want to understand how it works.

In that case, knowing the fields helps the most. It tells you what the parts of the object are.

Swine answered 16/3, 2009 at 10:8 Comment(2)
I can agree w/ qualifications but sorta understand why this was downvoted... not that said voters deigned to explain the problem. Qualifications: When coding classes for my use, I tend to do something like this: private fields at top, then private functions; then public stuff at bottom. Obviously adjusting for ordering dependencies. And I don't even use an IDE, just vim! But there's the Problem: Were I writing classes for others to use, I'd write with them in mind, i.e. with the most relevant things up front. That's just polite, esp if they also eschew whichever IDE is currently en vogueEllinger
i read a class to see how to use it. Only if the usage is not clear i then look at implementation details. Many people still use vim and emacs and don't have access to xwindows to run 'modern' IDEs.Brig
S
1

It is really helpful to the folks that will use your class to list the public interface first. It's the part they care about and can use. Protected and private can follow along after.

Within the public interface, it's convenient to group constructors, property accessors and mutators, and operators in distinct groups.

Sisco answered 21/11, 2008 at 13:22 Comment(0)
W
1

Note that (depending on your compiler and dynamic linker), you can retain compatibility with previous versions of a shared library by only adding to the end of the class (i.e. to the end of the interface), and not removing or changing anything else. (This is true for G++ and libtool, and the three part versioning scheme for GNU/Linux shared libraries reflects this.)

There's also the idea that you should order members of the class to avoid wasted space due to memory alignment; one strategy is to order members from smallest to largest size. I've never done this either in C++ or C though.

Winson answered 21/11, 2008 at 15:47 Comment(2)
I believe the recommendation is actually ordering from largest to smallest, isn't it? I'd have to look again, perhaps we can find a reference.Lignify
Here is good answer for order vs alignment.Rounds
B
1

Overall, your public interface should come before anything, because that's the main/only thing that users of your classes should be interested in. (Of course, in reality that doesn't always hold, but it's a good start.)

Within that, member types and constants are best first, followed by construction operators, operations, and then member variables.

Berzelius answered 16/3, 2009 at 9:39 Comment(0)
N
1

Almost all answers are opinion based, however one aspect that is not is binary compatibility.

Binary compatibility mainly affects changes to system DLLs and device drivers. If you're not interested in it, this answer isn't relevant.

  • Place public members before private members.
    • This is so you can mix and change private members to make bug fixes and minor changes, without affecting the location of the data the user is trying to manipulate.
  • Insert new public members at the end.
    • This again avoids affecting the position of existing public members.
  • The same ordering applies to vtable members as it does to regular fields.

Note how the user of class version 1 can still use class version 2:

            V1      V1      V2     V2
                   user           user 
public      [1]     1      [1]     1
            [2]     2      [2]     2
            [3]     3      [3]     3
                           [4]     4
private     [p1]           [p4]
            [p2]           [p5]
            [p3]           [p6]
                           [p7]
Nkrumah answered 24/8, 2021 at 12:1 Comment(0)
I
-1

Depends entirely on your preference. There is no "the right way".

When doing C++ in my own pet projects I personally keep convention that I put access modifier before each member or method declaration.

Intransigent answered 21/11, 2008 at 12:25 Comment(3)
I didn't mark you down but I suspect some did because putting an access modifier before each member is unnecessary and over-the-top. Frankly I find that it impacts legibility due to the added noise.Acrobatics
It makes your C++ look like Java. The question then is whether Java's "type an extra word per declaration" is better or worse than C++'s "access specifiers change global state, which is used implicitly by each declaration". Also whether you should do it the C++ way in C++ even if you prefer Java.Wamsley
I can't see why someone was downvoted so far for daring to have an opinion, in response to a question that's nearly entirely opinion-based - a well-defined reason for flagging that, I like to think, wouldn't even have gotten off the ground in today's presumably better-modded SO.Ellinger

© 2022 - 2024 — McMap. All rights reserved.