I understand what the typical access specifiers are, and what they mean. 'public' members are accessible anywhere, 'private' members are accessible only by the same class and friends, etc.
What I'm wondering is what, if anything, this equates to in lower-level terms. Are their any post-compilation functional differences between these beyond the high-level restrictions (what can access what) imposed by the language (c++ in this case) they're used in.
Another way to put it - if this were a perfect world where programmers always made good choices (like not accessing members that may change later and using only well defined members that should stay the same between implementations), would their be any reason to use these things?
Access specifiers only exist for compilation purposes. Any memory within your program's allocation can be accessed by any part of the executable; there is no public/private concept at runtime
Michael's answer is right. Access specifiers do not directly affect the resulting code.
However, access specifiers may resolve ambiguous identifier/overload errors that would otherwise prevent compilation.
class A {
private:
int x;
};
class B {
protected:
int x;
};
class C : public A, public B {
public:
int &get_x() { return x; } // only B::x is accessible, no error.
};
So they definitely serve a higher purpose than restricting the programmer.
The answer to your question could differ depending on the compiler, but in general there will be no difference. One could conceive though of an environment for which the compiled code might have different characteristics for those different accessibilities, but I'm not aware of any that exist.
Programmers can only make good choices when armed with the right information. Access modifiers are a way to signal to the programmer that certain things shouldn't be touched, and it has the side-benefit of enforcing correct behaviour.
There is no runtime impact. You could write a program with correct access modifiers, build it with, c++ -Dprotected=public -Dprivate=public file.cc, and it should build and produce almost exactly the same code (There are some hypothetical caveats such as data layout of classes).
Post-compilation, you are left with machine code (assembly) which has no notion of "public" or "private" (or of classes, members, etc). Everything is simply a memory address (whether it's code or data), and can be accessed just like any other memory address. The whole public\private distinction (as well as almost every other construct available in a high-level language) is purely for the benefit of the programmer, allowing the compiler to enforce a set of rules that are intended to make the intent of the code clearer and to help avoid potential bugs. Once compiled, your code doesn't know what language it was originally written in, much less what type of access specifiers were used.
That being said, it would be possible to rig a compiler so that it modifies the code whenever a private class member function is called in order to detect when the function is called inappropriately (add an extra parameter and set it to some expected value when the function is called from within the class; calling the function from outside of the class would provide the wrong value). The problem with this approach is what do you do now? Lock up? Do nothing and return invalid data? These types of problems are (relatively) easily detectable and correctable at compile time, so it is rare to see this sort of thing enforced at run time (outside of debugging or code profiling tools).
Related
Whats the significance of classes over data-structures or data-structures over classes?
Ok so The most basic ones can be that we can use "Access Specifiers In Classes" meaning we can prevent some and allow some to access our data.
next can be that data-hiding.
But whats the main thing that separates classes and data-structures? I mean why need data-structures when we have classes or vice-versa?
C++ has fundamantal types, and classes.
Struct and Class are both keywords that introduce a new class. There are slightly different defaults.
Data structures are an arrangement of data with some kind of invarient. They can be a class, they can contain classes, or they could be completely class free.
They are different categories of thing. It is like asking what the difference is between steel and an automobile.
In a course assignment, what the teacher is asking for is for you to know the definition the teacher or the text taught those terms meant. Terms mean what the context they are in tells them to mean. It is a matter of "are you paying attention" not "do you know this fact"; having asked it of the internet, you have already failed.
In terms of syntax, in C++ the only difference between a class and a struct is that members of a struct are public by default, while the members of a class are private by default.
From a perspective of implied design intent, however, there is a larger difference. struct was/is a feature of C, and was/is used (in both C and C++) to help the programmer organize Plain Old Data in useful ways. (for example, if you know every Person in your persons-database needs to store the person's first name, last name, and age, then you can put two char arrays and and int together in a struct Person and thereby make it more convenient to track all of that data as a unit, than if you had to store each of those fields separately).
C++ continues to provide that C-style struct functionality, but then goes further by adding additional features to better support object-oriented-programming. In particular, C++ adds explicit support for encapsulation (via the private and protected keywords), functionality-extension via inheritance, the explicit tying-together of code and data via methods, and run-time polymorphism via virtual methods. Note that all of these features can be approximated in C by manually following certain coding conventions, but by explicitly supporting them as part of the language, C++ makes them easier to use correctly and consistently.
Having done that, C++ then goes on to muddy the waters a bit, by making all of that new functionality available to structs as well as classes. (This is why the technical difference is so minor, as described in the first paragraph) However, I believe it is the case that when most programmers see a struct defined, they tend to have an implicit expectation that the struct is intended be used as a simple C-style data-storage/data-organization receptacle, whereas when they see a class, they expect it to include not just "some raw data" but also some associated business-logic, as implemented in the class's methods, and that the class will enforce its particular rules/invariants by requiring the calling code to call those methods, rather than allowing the calling code to read/write the class's member-variables directly. (That's why public member-variables are discouraged in a class, but less so in a struct -- because a public member-variable in a class-object contradicts this expectation, and violates the principle of least surprise).
I write some code c++
public class SomeClass
{
private:
int m_CurrentStatus;
int m_PreviouseStatus;
public:
int get_CurrentStatus() { return m_CurrentStatus; }
int get_PreviouseStatus() { return m_PreviouseStatus; }
}
in c# style
public class SomeClass
{
private: int m_CurrentStatus;
private: int m_PreviouseStatus;
public: int get_CurrentStatus() { return m_CurrentStatus; }
public: int get_PreviouseStatus() { return m_PreviouseStatus; }
}
Such usage access specifiers before each member of class is acceptable?
Or can trouble compiler spend more time for compilation or other effects?
Code successfully compiled with no warning.
What you describe is legal C++.
The impact on compilation times will depend on the compiler. However, practically, you will probably be hard pressed to detect any difference of compilation times.
There may be either impact or benefit on code readability - i.e. ability of a human to understand what is going on. Generally, people prefer "sections" (e.g. the declaration of several members following a single access modifier (public, private, or protected)) quite well, as long as the sections don't get too large (e.g. fill more than a screen when editing the code). So doing it the way you are may be unpopular with other developers. This is highly subjective though - different people will have different preferences. However, if you find other people objecting to your approach, listen to them - unless you are happy to be unpopular with other team members, lose jobs, etc etc.
There may or may not be an impact on layout of data members in the class. Different versions of the C++ standard make different guarantees but there are considerable freedoms for compilers to lay out classes differently. If you are writing code that relies on (or tests for) particular class layout (order of data members, offsets, etc) you might observe a difference. Or you might not. However, these things are permitted to vary between implementations (compilers) anyway so writing code that relies on specific layouts is often a bad idea anyway.
It's legal syntax and shouldn't upset the compiler, you can have as many public and private blocks as you want. I don't see that it's an improvement syntactically though.
It's certainly legal and free from compile time penalties to put access specifiers before each and every class member. You could also put 50 semicolons at the end of every line. It simply isn't canonical C++.
It is Legal and also very correct. You won't use an object oriented language if you want to have your members public. A basic usage of object oriented programming is information hiding.
The only thing that can trouble compiler in your case(in a matter of time), is that your function block is inside the class.
What do I mean?
If you have a main.cpp and a class.h , and your functions are declared and defined inside class.h, your compilation will take a little longer, rather than if your function body was in functions.cpp
It's perfectly legal syntax for C++,
except for the public keyword before class
and the missing semicolon (;) after the closing curly bracket of class.
BUT I've never seen something like that, I suppose it's surely not commonly used and, in my opinion, it adds nothing to code readability (on contrary, I personally find it more cumbersome to read).
I recently removed a private specified from a class definition because it was at the top, immediately after the class keyword:
class MyClass
{
private:
int someVariable;
// ...
I thought that it was redundant.
A coworker disagreed with this, saying that it effectively "hid" the private nature of the data.
Most of our legacy code explicitly states the access specifiers, and usually intermingles them inconsistently throughout the definition. Our classes also tend to be very large.
I'm trying to make my newer classes small enough so that my class definitions are similar to:
class MyClass
{
// 3-4 lines of private variables
protected:
// 3-4 lines of protected functions
public:
// public interface
}
which would allow omission of the redundant access specifier while (hopefully) keeping the private members close enough to the struct/class keyword for reference.
Am I sacrificing readability for brevity, or are the struct/class keywords sufficient?
If you are very familiar with all the default access levels then you probably won't see any difference in readability if you omit them whenever they are unnecessary.
However you will find that many people you work with aren't 100% sure about the default access level rules. This is especially true for people who regularly use different languages where the rules might be different in the different languages. As a result they might get the rules mixed up.
Always specifying the access is the safest option, if only to help the people you work with have one less thing to worry about.
Technically, "private" at the beginning of a class or "public" at the beginning of a struct is redundant, however I personally do not like the intermingled style but rather like to order by access and by declaration type. Readability is more important to me as brevity. So I would have a section "public methods", "private attributes" and so on and I format them as such:
class A
{
public: // methods
private: // methods
private: // attributes
};
This of course also generates redundant access declarations. Also, I like putting "public" stuff first because that's most important to users of the class. So, I need an access specifier at the beginning anyway. And I put "public" at the beginning of a "struct" as well.
While incorrect — strictly speaking — your coworker has a point; an experienced C++ programmer doesn't need the default access spoon fed to them, but a less experienced programmer might.
More to the point: most code I've seen and worked with puts the public stuff first, which renders the question moot.
I personally think that being very explicit is generally a good thing. The extra line of code is a small price to pay for the clarity that it adds.
In addition, it allows you to easily reorder your members (private must be first if it's omitted, which is really "backwards" from what you'd expect). If you reorder, and there's a private: modifier in place, other developers are less likely to break something.
Personally, I think it is much more clear with the private keyword included and I would keep it. Just to make sure it is private and everyone else knows it as well.
But I assume this is of personal taste and different for everyone.
I almost always arrange my classes backwards from yours: Public interface first, any protected interface second, and private data last. This is so that users of my classes can simply look at the public and protected interfaces at the top and need not look at the private data at all. Using that order then there's no possible redundancy and the question become moot.
If you prefer to organize yours in the way you outlined, I believe being explicit far outweighs the gain one of line of code. This way it's completely obvious to code readers what the intention is (for example if you change a struct to a class or the reverse at any point).
I often see the public part of a class/struct definition first, thus the protected/private stuff comes later.
It make sense, as a header file is meant to show what the public interface for your class actually is.
At the same time, why not use struct? public by default...
Still, it never hurts to be extra clear in your code as to what is going on. This is the same reason why I avoid the ternary operator and still put in the braces for an if statement that only has one line of code after it.
The most pressing issue though, is what are your companies code standards? Like them or not, that's the standard style you should do for your company, if they say do it such a way, you do it such a way.
I read the following statements from BRUCE ECKEL'S THINKING IN C++
1.Access specifier are part of structure and do not affect the object
created from "structure
Doubt:As we know the access blocks are not stored contiguously,
aint it that access specifier change the way object layout in memory
2.All of the access specification information disappear before the program is run
(during compilation).In a running program,object become the "region of storage"
and nothing more..thus we can break all the rules and access the memory directly
as you can in c
Doubt:Does it mean one can even access private member directly?please help me to comprehend the above statement
3.c++ is design to be pragmatic, not to aspire to abstract deal
Doubt:whats a meaning of being pragmatic?
1) Access specifier are part of structure and do not affect the object created from "structure"
Wrong actually, the order (in the layout) of data members within the same access specific (public, protected or private) is dictated by their order in the code, however no order is specified for data members with different specifiers.
class Foo
{
public:
int a;
int b;
protected:
int c;
int d;
};
The only thing we know is that a must come before b and c must come before d. abcd, acbd, acdb, cabd, cadb and cdab are all possible.
2) All of the access specification information disappear before the program is run
(during compilation).In a running program,object become the "region of storage"
and nothing more.. thus we can break all the rules and access the memory directly
as you can in c
The information is only used during compilation, but then compilation is what generate the running code. Therefore compilation ensures that you won't access private members. However, since direct memory manipulation is permitted, you could effectively access private members or functions if you wish, it's just highly error-prone to try and do it manually.
3) C++ is designed to be pragmatic, not to aspire to abstract the real
Pragmatic means that it's geared toward real use, with little consideration for purely theoretic arguments. Languages built from CS theory would include Haskell for example, which has an extremely sound mathematical background; on the other hand C++ has accumulated features that were deemed useful by its users.
Also, C++ does not hide the low-level details from you (like memory management). Good C++ code generally leave it up to the compiler and use idioms to try and abstract it (somewhat), but if necessary you can always get closer to the metal (even including Assembly code directly)... and sometimes (like memory management) you do have to pay attention to what you're doing.
class Foo {
int x, y;
public:
int z;
Foo(int a, int b) : x(a), y(b) {}
};
Foo foo;
You can get to the private member variables quite easily:
memset(&foo, int 0, sizeof(foo)); // wipes them all
fwrite(&foo, sizeof(foo), 1, fp); // dumps them to stream fp
As several commenters noted, this provokes undefined behavior under the C++ standard, so know your compiler before you attempt this (or better, don't). If you know how the compiler packs classes, you can even get more fine-grained access by hacks such as
struct PublicFoo {
int x, y, z; // order, padding, etc. depends on compiler
};
and casting a Foo * to a PublicFoo *. Nothing in the C++ runtime prevents that.
Is it only to allow logical grouping?
It gives you flexibility. For example, you might have a bunch of constructors, some public, some protected, some private - wouldn't you want them all grouped together?
Why would you force it? It doesn't help the compiler out at all, it doesn't make things objectively easier for a person to read. Part of the C/C++ philosophy is that the language doesn't make arbitrary rules that don't enable some sort of feature/functionality.
It does make things MUCH easier for code generation. Many coding styles use access specifiers more than once per class - first defining all the local types, then all constructors, then all the methods, then all the instance variables, etc...
C++ gives you enough rope to shoot yourself in the foot, but it's that same flexibility that lets you build elegant, maintainable, and well abstracted applications.
I think you are correct. Leaving it unforced allows users to group things as they see fit for better code readability.
The compiler may organize things differently in memory.
edit: as per the spec:
§9.2 clause 12 (1998 and 2003 standards):Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).
I found this information in a related SO question
My guess is that it is an outgrowth of the C philosophy, which assumes that you know what you are doing and gives you the maximum flexibility. It is like allowing a single = in an if statement.
I actually take advantage of this in a slightly unpleasant way: A code idiom I often use is a private member, with public accessor functions.
I have a MACRO (shudder) which automatically generates these from a single line.
example:
PROPERTY(int, MyVal);
...generates:...
private:
int fMyVal;
public:
void setMyVal(const int f) { fMyVal = f; };
int getMyVal() { return fMyVal; };
This works fine as long as you remember that the PROPERTY macro switches the current visiblity, which is not pleasant....
eg:
protected:
int v1;
PROPERTY (int, v2) // fv2 is private with public accessors
int v3; // whoops. f3 is public,
In "The C++ Programming Language, 3rd edition," Stroustrup says this is to make code generation easier.
Although it does make sense that the position of each field in the actual binary is based on which order that field was declared in the source code, so this allows somebody to maintain some sort of layout compatibility with C or even other languages/specs.