In C++, why is private the default visibility for members of classes, but public for structs?
C++ was introduced as a superset of C. Structs were carried over from C, where the semantics of their members was that of public. A whole lot of C code exists, including libraries that were desired to work with C++ as well, that use structs. Classes were introduced in C++, and to conform with the OO philosophy of encapsulation, their members are private by default.
Because a class is a usual way of doing object orientation, which means that member variables should be private and have public accessors - this is good for creating low coupling. Structs, on the other hand, have to be compatible with C structs, which are always public (there is no notion of public and private in C), and don't use accessors/mutators.
Probably for backwards compatibility with C structs. This way structs declared in C code will continue to work the same way when used in C++ code.
Direct answer:
Default visibility for struct in C++ is public and for class it's private.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
As far as I know the main difference (and may be the unique one) between classes and structs in C++ is that classes have their members private by default and structs have theirs public by default.
However, and probably because I was a C-developer before, I still continue to declare structs to hold only "public" fields, and I almost never declare methods (except constructors to initialize members).
I also want to take advantage of C++ inheritance for structs.
My questions are:
Even if the language allows it, is it a good practice to inherits structs ?
Is it possible to prevent a struct to declare a virtual method, which will create a vtable and modify the size of the struct ?
Thank you
classes have their members private by default and structs have theirs public by default.
Structs also inherit public by default, where classes inherit private by default.
Even if the language allows it, is it a good practice to inherits structs ?
Sure. It works exactly as you would expect.
Is it possible to prevent a struct to declare a virtual method, which will create a vtable and modify the size of the struct ?
Not yet. There is a proposal for C++20+ (P0707) to allow exactly this, but it's still pretty young and not implemented far enough to be used anywhere. In particular, search for "3.6 plain_struct" to see how they enforce plain structs to be that.
In general I would recommend using a struct when you're using it as a "struct" sort of function - holding data without invariants. If you have invariants, you should keep them using encapsulation and data hiding, so it should be a class.
Just want to address this question:
Even if the language allows it, is it a good practice to inherits structs ?
You should rid yourself of connotation that "struct" indicates POD. Sometimes, the most reusable components are those that don't encapsulate anything, despite having some behavior.
For instance, consider this meta-function:
template<typename T> struct is_foo : std::false_type {};
template<> struct is_foo<Foo> : std::true_type {};
All of the above types (and the types behind the aliases for true and false) are declared with the struct keyword. This is simply because having everything public by default forwards the behavior we want without us having to spell it out every time.
Another time when you find yourself inheriting from a "struct" is when extending a C library. If the library defines a structure named struct Bar that is used to communicate with it, the easiest way you can add functionality to it, is by inheriting from Bar. Like this:
class ExtendedBar : Bar {
void mem_func() {
//Need to call the C library function? No problem
c_library_func(this); // ExtendedBar is-a Bar
}
};
The only important difference is the default accessibility levels. And the only thing you should concern yourself with (IMO) is which default accessibility works best for your purpose.
Even if the language allows it, is it a good practice to inherits structs?
Yes it is. Just look around C++ STL (Standard Template Libraries). You will find struct in abundance.
Is it possible to prevent a struct to declare a virtual method, which will create a vtable and modify the size of the struct ?
No.... as of now.. As soon as you declare virtual functions.. the vtable will be created for struct
Structs vs Classes
You are correct, a primary difference between struct and class in C++ is default access levels. Without an explicit access modifier, class members are private, and struct members public. Struct members can also be made private using an access modifier. Keep in mind; this also applies to inherited classes and structs.
As for a general recommendation: many use structs only for data and classes for everything with behavior [1]. In other words, structs for POD (Plain Old Data) types[2], this is a widespread practice. It does not mean you cannot have functionality related to accessing and setting data members, setting up constructors, destructors, etc. "If more functionality is required, a class is more appropriate. If in doubt, make it a class." Their guide also recommends structs instead of classes for functors and traits.
You have to keep in mind, aside from any technical upsides or downsides, there are other reasons to enforce specific practices and standards in a team, and on a project basis. As also mentioned in Google's style guide, we can add semantic meaning to the data structures we use. As a team member, I would want to know if structs have behavior or not. It would be nice to know, for instance, that all structs are just POD types.
The Joint Strike Fighter coding standard specifies, "A structure should be used to model an entity that does not require an invariant." While "A class should be used to model an entity that maintains an invariant." And that public and protected data should only be used in structs, not in classes. Their rationale for this is that a class can't control access to public members; hence, all data in a class should be private. Consider the needs of your project when deciding on coding standards.
Struct inheritance
When thinking about inheritance, you must consider what public inheritance means versus private inheritance. Keep in mind what access levels the new, derived one will have, and if it makes sense to inherit your structs. Struct members can be made private, if you inherit from this, the derived one will not have access to the base's private members.
struct base {
int public_data;
private:
int private_data;
};
struct derived : base {
derived() {
public_data = 1;
// private_data = 1; // no access, won't compile
}
};
In other words, inheritance might be considered more of a logical issue than an implementation one.
There is nothing, technically, fundamentally wrong with inheriting structs. It might be a benevolent practice, and it might, in some cases, be beneficial and make a lot of sense.
Keep in mind, in C++, structs can inherit from classes and vice versa.
See this question for more information on vtables: When is a vtable created in C++?
[1] https://google.github.io/styleguide/cppguide.html#Structs_vs._Classes
[2] http://en.cppreference.com/w/cpp/concept/PODType
As far as I know the main difference (and may be the unique one) between classes and structs in C++ is that classes have their members private by default and structs have theirs public by default.
The only difference between classes declared with the keyword struct, and those declared with the keyword class is indeed the default access specifier (which applies to bases too as well as members).
Indeed, the easiest way to understand structs is to understand that they are classes.
Even if the language allows it, is it a good practice to inherits structs ?
Sure. It is OK to inherit a class, and structs are classes.
Is it possible to prevent a struct to declare a virtual method, which will create a vtable and modify the size of the struct ?
No, there is no such feature as far as I know.
Given struct A { ... };, struct B { A a; ... } is much safer than struct B : A { ... }.
I suggest not inheriting is better than inheriting with non-virtual destructor. The only thing you lose is the implicit conversion from B*, B& to A*, A& etc. However you still have the explicit B b; b.a for those circumstances.
I'm working on the graphics code for a game library in Java. I made package called com.engine.graphics. In this package, I have a lower-level class called VertexArrayObject. This class is used by "client-level" classes that clients will use; however, I do not want to give clients access to VertexArrayObject, since it would only serve to complicate their understanding of my library. Thus, I gave VertexArrayObject the default access specifier; that way, only classes within com.engine.graphicshave access to it, and also tells clients that they do not need to know what it is.
Just like there is this standard convention for Java, I figured there must be some standard convention for C++ for dealing with this; however, my internet searches have yielded no results.
So, my question is, what is the convention? And if there isn't one, what is the best approach?
C++ does not have a notion of 'package' thus no 'package-protection' is technically possible. (There is a proposition for modules, but it will not be included even in the upcoming C++17 standard).
There are many ways of hiding the class from external world or restricting access to it, on syntax level you can resort to:
nested classes which may be declared private (you should be familiar with them from Java, except they are "static" by default and cannot access non-static enclosing class members) link;
friend classes that can access any private members of the given class link;
friend functions if you want to restrict access to only certain functions, including member functions of another class;
private/protected inheritance where only the class members are aware of the inheritance link.
Having a lot of friend classes and functions is a mess, but there is a reason for requiring explicit listing of those: they break the encapsulation principle.
Finally, you can use either "private implementation" idiom (aka pimpl, aka opaque pointer) that consists in defining a visible class holding a pointer to the implementation class and forwarding all calls while the implementation class is defined in a separate cpp file or the façade design pattern.
Chose whatever seems appropriate for the given class relation. Standard library tends to prefer nested classes while Qt, a popular graphic library, relies on pimpl.
Suppose I have a purely virtual class, can I do something like this in C++:
class ITreatable
{
public:
bool hasBeenTreated; // <- Can this be here?
virtual bool Treat() = 0;
};
And if not, how can I ensure that classes which inherit ITreatable have a member variable called hasBeenTreated? Is that possible? Is there some kind of best practice that avoid having to do this / advises against it?
Thanks
Edit: Also how would I define a constructor for such a class?
Edit2: I understand that public member variables are bad practice, I'm just wondering if the design in general is a good idea in C++ or not.
Absolutely.
Strictly speaking, there is no such thing as a "virtual class". I understand that you are using the term to mean a class constructed of only data members and virtual member functions.
Consider that only functions can be virtual; if you wish for data members to be accessed polymorphically, you must do this through functions. Thus, use virtual getter/setter functions, and keep your data members private.
Acordingly to MSDN an interface has these characteristics:
An interface class (or struct) must be declared within a namespace
and may have public or private accessibility. Only public interfaces
are emitted to metadata.
The members of an interface can include properties, methods, and
events.
All interface members are implicitly public and virtual.
Fields and static members are not permitted.
Types that are used as properties, method parameters, or return
values can only be Windows Runtime types; this includes the
fundamental types and enum class types.
So I would response to your question with
NO if you want an interface
and
Yes if you just use abstract classes, but as the others say, make them private and use public getters and setters
Yes.
There is no concept of a "pure virtual" class in C++, merely abstract classes with virtual members.
As for whether there is a best practice, I would say that the biggest practice that should be followed in this example is not to use public variables. Rather, have a setter/getter defined in the base class that modifies a private variable.
That is possible. C++ doesn't have interfaces enforced by the language, so your example acts like normal class definition without any special rules.
It's considered bad practice to declare variables as public in classes. You might want to make it private and declare accessor/mutator for it or declare it as protected.
After finishing my C++ class it seemed to me the structs/classes are virtually identical except with a few minor differences.
I've never programmed in C before; but I do know that it has structs. In C is it possible to inherit other structs and set a modifier of public/private?
If you can do this in regular C why in the world do we need C++? What makes classes different from a struct?
In C++, structs and classes are pretty much the same; the only difference is that where access modifiers (for member variables, methods, and base classes) in classes default to private, access modifiers in structs default to public.
However, in C, a struct is just an aggregate collection of (public) data, and has no other class-like features: no methods, no constructor, no base classes, etc. Although C++ inherited the keyword, it extended the semantics. (This, however, is why things default to public in structs—a struct written like a C struct behaves like one.)
While it's possible to fake some OOP in C—for instance, defining functions which all take a pointer to a struct as their first parameter, or occasionally coercing structs with the same first few fields to be "sub/superclasses"—it's always sort of bolted on, and isn't really part of the language.
Other that the differences in the default access (public/private), there is no difference.
However, some shops that code in C and C++ will use "class/struct" to indicate that which can be used in C and C++ (struct) and which are C++ only (class). In other words, in this style all structs must work with C and C++. This is kind of why there was a difference in the first place long ago, back when C++ was still known as "C with Classes."
Note that C unions work with C++, but not the other way around. For example
union WorksWithCppOnly{
WorksWithCppOnly():a(0){}
friend class FloatAccessor;
int a;
private:
float b;
};
And likewise
typedef union friend{
int a;
float b;
} class;
only works in C
I'm going to add to the existing answers because modern C++ is now a thing and official Core Guidelines have been created to help with questions such as these.
Here's a relevant section from the guidelines:
C.2: Use class if the class has an invariant; use struct if the data members can vary independently
An invariant is a logical condition for the members of an object that a constructor must establish for the public member functions to assume. After the invariant is established (typically by a constructor) every member function can be called for the object. An invariant can be stated informally (e.g., in a comment) or more formally using Expects.
If all data members can vary independently of each other, no invariant is possible.
If a class has any private data, a user cannot completely initialize an object without the use of a constructor. Hence, the class definer will provide a constructor and must specify its meaning. This effectively means the definer need to define an invariant.
Enforcement
Look for structs with all data private and classes with public members.
The code examples given:
struct Pair { // the members can vary independently
string name;
int volume;
};
// but
class Date {
public:
// validate that {yy, mm, dd} is a valid date and initialize
Date(int yy, Month mm, char dd);
// ...
private:
int y;
Month m;
char d; // day
};
Classes work well for members that are, for example, derived from each other or interrelated. They can also help with sanity checking upon instantiation. Structs work well for having "bags of data", where nothing special is really going on but the members logically make sense being grouped together.
From this, it makes sense that classes exist to support encapsulation and other related coding concepts, that structs are simply not very useful for.
It's not possible to define member functions or derive structs from each other in C.
Also, C++ is not only C + "derive structs". Templates, references, user defined namespaces and operator overloading all do not exist in C.
One more difference in C++, when you inherit a class from struct without any access specifier, it become public inheritance where as in case of class it's private inheritance.
C++ uses structs primarily for 1) backwards compatibility with C and 2) POD types. C structs do not have methods, inheritance or visibility.
Since nobody has mentioned it yet, there is actually another difference besides the default visibility. It turns out that class and struct are actually different things in MSVC.
class Vector2;
struct Vector2 {
double x;
double y;
};
This is 1 symbol on most compilers, but 2 different symbols on MSVC. Just this code by itself does compile fine. However, if you try to use it in more complex scenarios you will run into errors where this does not compile on MSVC because it gets confused about the symbols.
Could anybody please tell me what is the main difference
between C & C++ structures.
In C++ struct and class are the exact same thing, except for that struct defaults to public visibility and class defaults to private visiblity.
In C, struct names are in their own namespace, so if you have struct Foo {};, you need to write struct Foo foo; to create a variable of that type, while in C++ you can write just Foo foo;, albeit the C style is also permitted. C programmers usually use typedef struct {} Foo; to allow the C++ syntax for variable definitions.
The C programming language also does not support visibility restrictions, member functions or inheritance.
In C++, structures behave like classes, allowing methods, constructors, destructors etc...
The main difference between classes and C++ structures is that everything inside structures is public by default, while everything inside classes is private by default. (ie: nothing outside can access them directly)
There are several differences in C and C++ structure
In C we define struct keyword is necessary to create the structure type value while in C++ it is not necessary.
In C there is no function inside the structure while in C++ we can define function that can access the data members of structure directly( Function is names as method in C++ )
There is no concept of access modifier inside the structure in C while in C++ we can find the access modifier (eg. private and public ). By default all are public.
Structure in C can not have static members while in C++ structure can have static members.
Size of empty structure is constraint violation in C, but it is always 1 in C++.
We can have both pointers and references to struct in C++, but only pointers to structs are allowed. (References aren't feature of C language)
C structs is more akin to a definition of a composite data structure
C++ structs can be thought of as a class but scope of all member variables are defaulted to public.
In addition to the answers above, remember that C++ structures support inheritance and so can contain pointers to vtables. This can make a big difference when serializing and deserializing these structures across processes. Templates are supported too.
C : we can't define function inside the structure in c.
C++ : We can define function inside the structure in c++.