views:

194

answers:

5

A "traditional" C++ class (just some random declarations) might resemble the following:

class Foo
{
public:
  Foo();
  explicit Foo(const std::string&);
  ~Foo();

  enum FooState
  {
    Idle, Busy, Unknown
  };

  FooState GetState() const;
  bool GetBar() const;
  void SetBaz(int);

private:
  struct FooPartialImpl;

  void HelperFunction1();
  void HelperFunction2();
  void HelperFunction3();

  FooPartialImpl* m_impl; // smart ptr
  FooState m_state;
  bool m_bar;
  int m_baz;
};

I always found this type of access level specification ugly and difficult to follow if the original programmer didn't organize his "access regions" neatly.


Taking a look at the same snippet in a Java/C# style, we get:

class Foo
{
  public: Foo();
  public: explicit Foo(const std::string&);
  public: ~Foo();

  public: enum FooState
  {
    Idle, Busy, Unknown
  };

  public: FooState GetState() const;
  public: bool GetBar() const;
  public: void SetBaz(int);

  private: struct FooPartialImpl;

  private: void HelperFunction1();
  private: void HelperFunction2();
  private: void HelperFunction3();

  private: FooPartialImpl* m_impl; // smart ptr
  private: FooState m_state;
  private: bool m_bar;
  private: int m_baz;
};

In my opinion, this is much easier to read in a header because the access specifier is right next to the target, and not a bunch of lines away. I found this especially true when working with header-only template code that wasn't separated into the usual "*.hpp/*.inl" pair. In that scenario, the size of the function implementations overpowered this small but important information.


My question is simple and stems from the fact that I've never seen anyone else actively do this in their C++ code.

Assuming that I don't have a "Class View" capable IDE, are there any obvious drawbacks to using this level of verbosity?

Any other style recommendations are welcome!

+4  A: 

Personally, I find it very annoying to have to specify the access qualifier for every symbol. It makes things harder to read, not easier, and encourages the very bad habit of freely mixing private and public stuff throughout the class definition. I see this kind of mess all the time. In C#, I try to mitigate this with #region private, etc, which hopefully encourages future maintainers to keep things clean.

Marcelo Cantos
Ha! I win by 4 seconds. +1 :)
Billy ONeal
Re: regions; When I work in VS and write Windows-specific code, I try to use the #pragma region / endregion directives too. It's quite nice that VS supports this for C++.
PolyTex
+1  A: 

There's nothing wrong with it, though you will raise eyebrows. The primary advantage of keeping the access specifiers separate is it encourages placing all the private members and methods at the top of the class -- together.

If your class is too big to fit on one screenfull than it probably should be either broken up into more than one class, and/or any implicitly inline functions should be explicitly declared inline with the implementation moved out of the class.

Billy ONeal
I don't know what it is, but the first version just looks "off" to me. Maybe it's because I've been working mostly in C# for the last few weeks?
PolyTex
@PolyTex: Maybe, but in that case I defer to Rahul G - I hate Unicorns' answer. (I can't believe I just seriously typed that...)
Billy ONeal
@Billy ONeal: You needn't have included *I hate Unicorns* in my name. I edited my name on 1st of April and now I am stuck with it for a month. :(
missingfaktor
@Rahul G: Do you have a meta or Server Fault or Super User account? If so you can "Copy profile" from those accounts and it will fix your name. (see http://meta.stackoverflow.com/questions/45208/possible-feature-request-revert-a-display-name-change-within-24-hours and http://meta.stackoverflow.com/questions/45200/add-warning-when-changing-display-name )
Billy ONeal
A: 

The disadvantage to the latter approach is that is rarely done, and it is not a good idea to surprise other developers in this way, and it requires the access modifier to be typed a million times. Using the traditional approach will save having to needlessly type the modifier over and over and is also the expected approach.

Michael Aaron Safyan
+9  A: 

"When in Rome, do as the Romans do."

I, having spent a lot of time with Java, like the style of specifying access specifiers for every field and method separately. However when I am programming in C++, I always use the style shown in your first code snippet.

missingfaktor
Good to see you got your name fixed :D
Billy ONeal
Yes, it is a good thing.
GMan
Is there a process? I went and named myself after a couple grains…
Potatoswatter
@Potatocorn: See the comments below Billy's answer.
missingfaktor
@Rahul: Woohooo!!
Potatoswatter
Rome? THIS. IS. SPAR-TAAA!11
PolyTex
A: 

Indeed, semantically it makes no difference but you will do yourself and your colleagues a great favour if you'll just follow what's accepted.

Personally I like my class like so:

struct S {
    S(int m) : m(m) { }
    S(const S& o);
    S& operator=(const S& o);

    void f() const;
    std::string g();

private:
    void help();

private:
    int m;
};

But I will change my manners without thinking twice if I commit into a repository that isn't strictly mine, because I know how appreciative I'd be if someone would commit their code to my repositories following my customs.

wilhelmtell