Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Private variables are a way to hide complexity and implementation details to the user of a class. This is a rather nice feature. But I do not understand why in c++ we need to put them in the header of a class. I see two annoying downsides to this:

  • It clutters the header from the user
  • It force recompilation of all client libraries whenever the internals are modified

Is there a conceptual reason behind this requirement? Is it only to ease the work off the compiler?

share|improve this question
    
you can declare a empty struct in the header but then you may only use pointers to such a struct when you use it (and you can't allocate one) –  ratchet freak Apr 10 '12 at 9:57
2  
@ratchetfreak: No, empty (struct foo{};) is not allowed, but forward declarations (struct foo;) are. –  MSalters Apr 10 '12 at 12:43
    
@MSalters that's what I meant –  ratchet freak Apr 10 '12 at 12:47
add comment

3 Answers

up vote 35 down vote accepted

It is because the C++ compiler must know the actual size of the class in order to allocate the right amount of memory at instantiation. And the size includes all members, also private ones.

One way to avoid this is using the Pimpl idiom, explained by Herb Sutter in his Guru of the Week series #24 and #28.

Update

Indeed, this (or more generally, the header / source file distinction and #includes) is a major hurdle in C++, inherited from C. Back in the days C++ C was created, there was no experience with large scale software development yet, where this starts to cause real problems. The lessons learned since then were heeded by designers of newer languages, but C++ is bound by backward compatibility requirements, making it really hard to address such a fundamental issue in the language.

share|improve this answer
    
Isn't this kind of information only contained in the class library? Is it used for linking? –  Simon Apr 10 '12 at 10:02
    
@Simon, what do you mean by "class library"? –  Péter Török Apr 10 '12 at 10:07
    
I mean the collection of object files containing the class definition and methods –  Simon Apr 10 '12 at 10:09
4  
When C++ was created, AT&T/Bell Labs (Stroustrups employer at the time) certainly had experience with large-scale C development. Their 5ESS phone switch software was at the time probably the largest single C program in the world. Early ideas about OO are already visible in that code base, and Cfront mimicked those techniques. However, the notion of private is more modern. –  MSalters Apr 10 '12 at 12:47
1  
In C, you'd simply put the allocator in a library function; the client wouldn't be able to allocate such a structure at all. This increases the overhead a bit, but makes migrating the code across versions trivial so it's often worthwhile. However, it does tend to lead to a code style that's very distinct from that seen with C++. –  Donal Fellows Apr 10 '12 at 14:07
show 5 more comments

The class definition needs to be sufficient for the compiler to produce an identical layout in memory wherever you've used an object of the class. For example, given something like:

class X { 
    int a;
public:
    int b;
};

The compiler will typically have a at offset 0, and b at offset 4. If the compiler saw this as just:

class X { 
public:
    int b;
};

It would "think" that b should be at offset 0 instead of offset 4. When code using that definition assigned to b, code using the first definition would see a get modified, and vice versa.

The usual way to minimize the effects of making changes to the private parts of the class is usually called the pimpl idiom (about which I'm sure Google can give a great deal of information).

share|improve this answer
    
I am asking about a design decision. Of course you would need to put the private member declaration somewhere for the language to work. But why should it be in the header and not in a more private place? –  Simon Apr 10 '12 at 10:04
6  
@Simon: The header is all the compiler sees to tell it what the class/struct looks like. There have been discussions of adding something like modules to C++, which would hide that sort of data a bit more, but so far it hasn't been approved (though it hasn't been entirely dropped either). –  Jerry Coffin Apr 10 '12 at 10:05
2  
Still, a trivial rule would be to allocate such ".cpp-defined" private members last. That means the offsets of public and "normal" private members would not depend on them. IMO the real reason is that you can't inherit from such a class, since the derived part has to follow even those private members. –  MSalters Apr 10 '12 at 12:51
add comment

There are most likely several reasons. While private members can't be accessed by most other classes, they can still be accessed by friend classes. So at least in this case they may be needed in the header, so the friend class can see they exist.

The recompilation of dependent files may depend on your include structure. Including the .h files in a .cpp file instead of another header can in some cases prevent long chains of recompilations.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.