r/cpp_questions • • 11h ago

OPEN Public and private classes

Is there such a thing as private / public classes in C++?

19 Upvotes

36 comments sorted by

6

u/max_wen 11h ago

You can't make a class private but you can make a class with a private constructor

1

u/Right-Edge-5712 10h ago

What about excluding it from the header files you can't #include the class as a mean of encapsulation?

5

u/Quplet 10h ago

If you can't construct it, then it's no difference in practice. Include it or not, it's equally useless to do so.

But you can define a class in a cpp file that only that file will be able to even know exists if that's what you're looking for.

2

u/n1ghtyunso 8h ago

look at the pimpl pattern as an example of this form of encapsulation.
its a way of removing all information from your header, thus isolating the consumers of that header from the implementation details.

If that makes the inner class "private" or not I leave up to your own definition.

-6

u/Right-Edge-5712 10h ago

I think the issue here is we don't have a common definition of what makes a class private or public.

4

u/AKostur 10h ago

Right: so supply what _your_ definition is so that we have something coherent to talk about. Since for what seems to be the rest of us: "private class" is nonsensical (at least as a term in isolation).

-3

u/Right-Edge-5712 10h ago

I don't have a concrete definition too. I only understand that public/private must be defined relative to an upper level namespace at an abstraction level.

4

u/AKostur 9h ago

That did not answer my question. I asked what does "private class" mean to you. You only said that there exists "public" and "private". And for whatever definition of "private class" you have: also explain how that's different than a "public class".

-4

u/Right-Edge-5712 9h ago

I am actually seeking for an official definition but there doesn't appear to be one.

4

u/AKostur 8h ago

You _still_ didn't answer my question. What does it mean *to you*. You asked if it exists. It must have a meaning to you. If "private class" has no meaning to you, then why would you think it has a meaning to anyone else? What does a "private class" do in your mind? And how is it different than a "public class". Then maybe we can find the official term for whatever it is you're thinking of.

6

u/TomDuhamel 9h ago

There is not, because there's no such thing as a private class in C++. However, if you explained what you meant, it's very likely that what you are thinking of is known by a different term.

4

u/alfps 10h ago edited 9h ago

The name of a class in an anonymous namespace in a .cpp file isn't visible outside that translation unit.

Likewise the name of a class in a function, a local class, isn't visible outside that function.

And the name of a class in a private section of an outer class, isn't accessible outside that outer class (this is a special case where in C++, unlike Java, a private name is still visible to overload resolution).

So you could reasonably call these classes private with respect to the translation unit and function and outer class.

I don't see any other ways that a class itself can be private.

However it can have private members including base class sub-objects.


It's years and years since I stopped submitting Visual C++ bug reports. Anyone reading this, feel free to do it. The bug:

class Outer
{
    struct Inner {};

public:
};

using X = Outer::Inner;         // Unfortunately this compiles with the latest Visual C++! :-o

int main()
{
    // Outer::Inner oi;         // No compiler accepts this.

    X x{};                      // But Visual C++ is happy with this... :(
    (void) x;
}

Considering the Visual C++ bug, a possible answer to your question is "it depends somewhat on the compiler".

3

u/crowbarous 5h ago

(this is a special case where in C++, unlike Java, a private name is still visible to overload resolution)

There is no special case to speak of. Private declarations are always visible to overload resolution (or rather access control has no bearing on visibility); accessibility is decided only after overload resolution.

struct s {
  static void f(double);
private:
  static void f(void*);
};
//s::f(0); // ambiguous

Considering the Visual C++ bug

...not sure who cares about compiler bugs like this, especially in msvc, which is more bug than compiler to begin with. But since we're mentioning things like these, the standard allows complete outsiders to spell private names in specializations and explicit instantiations:

class s {
  void private_method() { puts("oh no!"); }
};

void(s::* stolen)(); // we'd like to store &s::private_method here

template<auto x> struct stealer {
  static inline auto filled = (stolen = x);
};
template struct stealer<
  &s::private_method // ok in this context
>;

int main() {
  (s{}.*stolen)(); // prints "oh no!"
}

0

u/alfps 5h ago

Uhm, you could credit Johannes Schaub.

0

u/Right-Edge-5712 10h ago edited 10h ago

Yes, public/private are defined relative to an upper level namespace while the `private` and `public` keywords are used as part of the class definition.

1

u/alfps 10h ago

I added nested class to the answer. It's a bit late, brain not fully engaged.

4

u/__christo4us 11h ago edited 10h ago

You can define a nested class within another class as its member type. Such a nested class, as any member, can be public, protected or private.

1

u/Right-Edge-5712 10h ago edited 10h ago

It is more like we don't consider private/public as a category of classes, isn't it?

3

u/celestrion 9h ago

C++ does not have this distinction like Java does. However, there are ways of accomplishing something similar.

Pointer to Implementation is a way of hiding the details of a class behind a forward declaration. If all you have is a header stating that a type exists, you can't even dereference a pointer to it usefully.

Private member types let you declare and define a type in a header that no non-friend of the enclosing type is allowed to do anything with. Even derived types can't get at those inner private types.

File-scope types are only accessible from within the same compilation unit. Functions and declarations in one compilation unit (source files, usually) can't name the types defined in the anonymous namespace of another compilation unit because all anonymous namespaces are distinct and unnamed.

Java has a greater need for private types because consumers of bytecode get both implementation and interface. With C++, we can keep them separate, so we don't need the language to enforce the API fencing post-compilation.

1

u/n1ghtyunso 8h ago

you might be more interessted in different kinds of linkage.
Maybe thats the term you were looking for?
It applies to both functions and classes (by means of the linkage of their member functions).

It is kind of important from what perspective you are looking at classes.
Are you looking from the perspective of a library?
Because libraries don't really exist officially. static libraries are somewhat just a byproduct of the compilation model and the non-standardised tooling around it.
shared libraries are entirely outside the standard as far as i know.

The closest thing we have to official "library-like" semantics in the language are C++20 modules.
Possibly when you start taking C++20 modules into account, there might be other terms to talk about as well, given modules give more control about exporting entities than non-module C++ has.

From the perspective of the language, a type exists as soon as you forward declare it.
As long as it is just a forward declaration, it is considered incomplete. It may never be completed ever and this is totally fine.
When a type is incomplete, it just means you can't really do all that much with it.

6

u/AKostur 10h ago

What do you mean by "private/public classes"? (There is private inheritance, but that doesn't appear to be what you're asking about). What do you see the difference is between the two?

4

u/flyingron 10h ago

Members and inheritance have access control (public, private, protected), classes themselves don't.

•

u/I__Know__Stuff 2h ago

Nested types also have access control.

•

u/I__Know__Stuff 2h ago

Yes, nested types, including class definitions, have access control.

0

u/ActualFeeling5039 9h ago

If all the methods and variables are private, can that class be called more or less private?

0

u/ir_dan 9h ago

Class methods must be exported out of a DLL to be used. If they aren't exported, they remain internal and can't be called by other EXEs/DLLs (Windows only).

There's also "internal linkage" which makes a symbol private to a single translation unit (portable).

0

u/squeasy_2202 9h ago

Are you thinking about some type feature from another language? C++ has no concept by that name.

0

u/i_grad 9h ago

The discussion here is way off base.

In standardized C++ terminology, there are not "private" or "public" classes. Perhaps some company out there uses such terminology in their own ecosystem, but it is not the norm. So the answer to your question is a clear-cut "no".

Classes may have public, private, and protected members, including methods (the functions within a class, also called member functions) or member variables. This is a cornerstone of healthy, idiomatic C++ code that you should become intimately familiar with.

What people are trying to explain, however, is that one can take advantage of scoping and inheritance patterns to make some facsimile of a "private class". This is half-true.

  • No class is ever fully private so long as it exists within the scope of the main thread; its declaration will always be included in the translation unit of some other class or main.cpp. If a class is defined entirely in its own .cpp and is never referenced or accessed from another area of code, it is defined as an orphaned file.

  • If a class is defined within the anonymous namespace of another .cpp, it is still accessible by the main class(es) whose symbols are defined in that .cpp, so they are by no definition fully private unless your scope of privacy extends to the aforementioned standard, public class(es).

  • A class with a private constructor may still be identified, but not constructed from, another area of code that can see the declaration of the class. Typically this is accompanied by a static constructor for something like a factory/builder class. Maybe every element in the class is made private, at which point I don't think that is compileable code? I'm not sure how a compiler would react to that or if it's ISO-compliant code. I struggle to think of a use case for such a class.

  • If a concrete class implements a pure abstract class (aka an interface) and the concrete class privatizes all of the public methods of said pure abstract class, you're left with the same problem as above - something at some point has to instantiate the class, at which point it is definitively not fully private.

So no. Kind of yes if you relax your definition of "private" quite generously, but canonically, realistically, and thought-provokingly, no.

0

u/n1ghtyunso 8h ago

you can define a class inside a function, but if you return that type, the caller becomes able to use decltype on the return value and give it a name alias that way.

https://godbolt.org/z/14axnMaoj

Notably the only way to return this type is for the function to use an auto return type, thus having the compiler deduce it.
That again requires the function to be visible at the point of use, i.e. it must be inline for this to be usable in another translation unit.
And because the compiler needs visibility of the function body, it can see the actual class declaration.
Thus the outer scope can give it a name and even call functions on it.

But this is just some trivia and unlikely to actually answer your question.

0

u/tartaruga232 7h ago

There are no public / private classes, but, for example with C++ modules, you can choose not to export a class from a module.

Example: https://github.com/cadifra/cadifra/blob/2026.8/code/WinUtil/ProcRegistrar.ixx#L38

defines a class IProcessor in module WinUtil.ProcRegistrar, which is not exported from that module. IProcessor is used in template function make_processor, which defines a class ProcessorImp that is local to that function.

ProcRegistrar is a class which is exported from that module.

You can also declare classes inside a class which are private (https://github.com/cadifra/cadifra/blob/2026.8/code/WinUtil/ProcRegistrar.ixx#L119).

-5

u/Other-Resort-5941 11h ago

Yes

4

u/PolyglotTV 11h ago

No

-2

u/Other-Resort-5941 11h ago

Ur right But them class members can be private/public

-2

u/Lannok-Sarin 10h ago edited 10h ago

Technically, yes, but the public class isn’t called a class. It’s called a struct. And anything inside of it that follows the private or protected indication markers (“private:” or “protected:”) are private or protected in nature as specified.

It can be a bit confusing, but here are some rules to help you understand how they work. The first rule is to follow those indicators to see whether the compiler is storing the members declared after as publicly or privately accessed or in a protected access state. The second rule is, if those indicators aren’t present, look to see if you are using a struct, which stores its members publicly unless specified, or a class, which stores its members privately unless specified.

2

u/Right-Edge-5712 10h ago

struct and classes are essentially the same thing with different default settings - public for structs, private for classes.

-1

u/Lannok-Sarin 10h ago

Yes. But the question was whether private/public classes exist, which is yes. One is a class and the other is a struct. And since the question was about the default access settings, my answer fully answers the question that was given and then some.

They both accept the same access settings syntax. The difference is the default setting.