Related
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've found myself that I tend not to have private class functions. If possible, all candidates to private class function rather I put in to unnamed namespace and pass all necessary information as function parameters. I don't have a sound explanation why I'm doing that but at least it looks more naturally to me. As a consequence I need to expose less internal details in the header file.
What is your opinion - is it correct practice?
In the semi large projects where I usually work (more than 2 million lines of code) I would ban private class functions if I could. The reason being that a private class function is private but yet it's visible in the header file. This means if I change the signature (or the comment) in anyway I'm rewarded sometimes with a full recompile which costs several minutes (or hours depending on the project).
Just say no to that and hide what's private in the cpp file.
If I would start fresh on a large c++ project I would enforce PIMPL Idiom: http://c2.com/cgi/wiki?PimplIdiom to move even more private details into the cpp file.
I've done this in the past, and it has always ended badly. You cannot pass class objects to the functions, as they need to access the private members, presumably by reference (or you end up with convoluted parameter lists) so you cannot call public class methods. And you can't call virtual functions, for the same reason. I strongly believe (based on experience) that this is A Bad Idea.
Bottom line: This sounds like the kind of idea that might work where the implementation "module" has some special access to the class, but this is not the case in C++.
It basically comes down to a question of whether the function in question really makes sense as part of the class. If your only intent is to keep details of the class out of the header, I'd consider using the pimpl idiom instead.
I think this is a good practice. It often has the benefit of hiding auxiallary structures and data types as well, which reduces the frequency and size of rebuilds. It also makes the functions easier to split out into another module if it turns out that they're useful elsewhere.
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).
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 7 years ago.
Improve this question
Is it appropriate to access a class' private members by casting it to a void pointer and then to a struct?
I don't think I have permissions to modify the class that contains the data members that I need to access. I don't want to take a risk accessing the data members in an indirect way if it is not ethical.
EDIT: Had to edit this further... I am pretty sure the class wouldn't be modified, so it's ok to that extent... my only concern is, if the person who coded that class gets to know of this, it might not go down well with him :(.
Let's not consider ethics for a moment. Let's consider the standard.
What you are proposing to do is nonstandard. See section 9.2, clause 12 of the standard. "The order of allocation of nonstatic members separated by an access-specifier is unspecified." Therefore, if you have a class with private members, and a struct with no private members, the standard does not guarantee that the members will be in the same order.
Therefore, if your hack works, it works only by accident, that the compiler writers happened to do it that way. There is no guarantee that it will work on another compiler, a later version of the same compiler, or with different class layouts.
Not to mention that, if you don't have authority to modify the class (say, to provide a simple accessor function), you probably don't have authority to object if any implementation detail in the class changes. (One of the ideas behind public and private is to distinguish what is promised from what is freely changeable.) Therefore, the layout may change, or the member might come to mean something different, or be removed altogether.
Herb Sutter wrote a Guru of the Week column on this issue.
Oh, as far as the ethics go? If you really, really have to do something like this, and you can't get out of it, document it very carefully. If your coding standards have some sort of procedure to flag nonstandard behavior, use them. If not, be very careful to note it in a way it won't be overlooked when something goes wrong.
I'm not sure that "ethics" really come into it. It busts the heck out of encapsulation though.
EDIT: I would almost never accept this if I were performing a code review. You'd have to work really hard to convince me there's no way of designing around the need for this. It's possible you'd succeed, but there'd have to be major warnings all over the place, and rock hard unit tests to make sure that if anything changed to break it, you'd know quickly.
I've just added an entry to my blog that shows how it can be done in a completely conforming way. Here is an example on how you use it for the following class
struct A {
private:
int member;
};
Just declare a tag name and instantiate a robber like the following example shows (my post shows the implementation of the robber). You can then access that member using a member pointer
struct Amem { typedef int type; };
template class rob<Amem, &A::member>;
int main() {
A a;
a.*result<Amem>::ptr = 42; // Doh!
}
But actually, this doesn't show that c++'s access rules aren't reliable. The language rules are designed to protect against accidental mistakes - if you try to rob data of an object, the language by-design does not take long ways to prevent you.
The above is a way to access private and protected members in a conforming way. This one is another way to access protected members in a Standard conforming way. The basic idea is to use a member pointer
std::deque<int> &getAdapted(std::stack<int> &s) {
struct voyeur : stack<int>
{ using stack<int>::c; };
return s.*(&voyeur::c);
}
int main() {
std::stack<int> s;
std::deque<int> &adapted = getAdapted(s);
output(adapted); // print the stack...
}
No casting or type punning involved. It takes a pointer to a protected member of std::stack<int> through a class derived from it where that member name is public, so the compiler allows this. Then it uses it on a std::stack<int> object, which is allowed too.
I have had this happen to me since there was a very crappy source control system in place where for old versions of the application making changes to header files was pretty much impossible.
If some cases you just need to do a hack.
In the source file from which you need to access the private data member you can put in this as a first line:
#define private public
#define protected public
and access anything you want.
No. What you are doing is Pure Evil.
"Never say never". I'm sure somewhere in the universe, there's a situation that will force you to have to do this...
But I certainly would cringe if I had to do it. You truly need get lots of opinions on your situation before pulling the trigger. Can you describe your specific situation and maybe we could see if it makes sense or what better alternatives might exist?
In response to comment/question--
Define "permissions" -- institutional permission? That sounds like not a programming problem, but something to talk to whoever is asserting said permission. Maybe this is more of a political issue than a technical one? Again, I think we need more specifics--even if it was somewhat about the politics of the situation. That may or may not be deemed out of scope for the website, however.
If you feel the urge to do this, forget casting - just modify the class declaration in the header file:
class A {
private:
int x;
};
change that to:
class A {
public:
int x;
};
and you are good to go. Well, perhaps "good" is not quite the right word.
It's ethical, but it's usually lots of dirty code neighbouring with undefined behaviour and unportability. Do it only if you absolutely have to.
Ah, abstraction - you can't live without it and yet it is so painful to deal with sometimes :)
Anyway, ethics aside, what if the "owner" of the class decides to change the internal implementation, or simply reverses the order of the private data members?
The only "ethical" problem is what you are doing to the poor bastard who is going to have to figure out and maintain your code.
Private members are just that. He may, and most likely will, one day change that member. When that happens, you might not even notice as there most likely will still be memory there, just not the member you were expecting. Damn near any nearly impossible thing you can imagine might then start happening when your code is run. How is anybody ever going to be able to debug that?
Simple answer: No.
It is not ethical and it will turn into a maintenance nightmare at some point. The internal private members of a library can change and break your code. Developers of the library do not need to know (nor want to) that you are violating the encapsulation.
Classes usually have invariants over their methods that some times will not be documented, but accessing and changing the values from the outside can break those invariants. As an example, if you change the reserved space in a vector for a higher value, the vector will not allocate new space until it has filled the existing and that won't happen before hitting unallocated memory: your application will crash.
If the attribute is private, it is not for you to use it, only for the class itself or the the class' friends that know about the member, how to use it, how not to break it. If the programmer wanted you to change the field, it would be public.
I assume that this class is part of project you are working on.
There is one ethical problem here:
If in your company you see ownership of code as sacrum. Or worst you are disallowed to modify code that is not yours. Yes You may hurt feeling of person that maintain that class. Or angry him if his salary is related to his code.
so best is just to ask him for any help, and few suggestions eg. add getter function or change private to public - all based on your intuition of using that new code.
Hack that you have mention is really bed practice. If cant modify that code and maintainer dont wont to change anything. Consider using adapter design pattern.
As I understand, the pimpl idiom is exists only because C++ forces you to place all the private class members in the header. If the header were to contain only the public interface, theoretically, any change in class implementation would not have necessitated a recompile for the rest of the program.
What I want to know is why C++ is not designed to allow such a convenience. Why does it demand at all for the private parts of a class to be openly displayed in the header (no pun intended)?
This has to do with the size of the object. The h file is used, among other things, to determine the size of the object. If the private members are not given in it, then you would not know how large an object to new.
You can simulate, however, your desired behavior by the following:
class MyClass
{
public:
// public stuff
private:
#include "MyClassPrivate.h"
};
This does not enforce the behavior, but it gets the private stuff out of the .h file.
On the down side, this adds another file to maintain.
Also, in visual studio, the intellisense does not work for the private members - this could be a plus or a minus.
I think there is a confusion here. The problem is not about headers. Headers don't do anything (they are just ways to include common bits of source text among several source-code files).
The problem, as much as there is one, is that class declarations in C++ have to define everything, public and private, that an instance needs to have in order to work. (The same is true of Java, but the way reference to externally-compiled classes works makes the use of anything like shared headers unnecessary.)
It is in the nature of common Object-Oriented Technologies (not just the C++ one) that someone needs to know the concrete class that is used and how to use its constructor to deliver an implementation, even if you are using only the public parts. The device in (3, below) hides it. The practice in (1, below) separates the concerns, whether you do (3) or not.
Use abstract classes that define only the public parts, mainly methods, and let the implementation class inherit from that abstract class. So, using the usual convention for headers, there is an abstract.hpp that is shared around. There is also an implementation.hpp that declares the inherited class and that is only passed around to the modules that implement methods of the implementation. The implementation.hpp file will #include "abstract.hpp" for use in the class declaration it makes, so that there is a single maintenance point for the declaration of the abstracted interface.
Now, if you want to enforce hiding of the implementation class declaration, you need to have some way of requesting construction of a concrete instance without possessing the specific, complete class declaration: you can't use new and you can't use local instances. (You can delete though.) Introduction of helper functions (including methods on other classes that deliver references to class instances) is the substitute.
Along with or as part of the header file that is used as the shared definition for the abstract class/interface, include function signatures for external helper functions. These function should be implemented in modules that are part of the specific class implementations (so they see the full class declaration and can exercise the constructor). The signature of the helper function is probably much like that of the constructor, but it returns an instance reference as a result (This constructor proxy can return a NULL pointer and it can even throw exceptions if you like that sort of thing). The helper function constructs a particular implementation instance and returns it cast as a reference to an instance of the abstract class.
Mission accomplished.
Oh, and recompilation and relinking should work the way you want, avoiding recompilation of calling modules when only the implementation changes (since the calling module no longer does any storage allocations for the implementations).
You're all ignoring the point of the question -
Why must the developer type out the PIMPL code?
For me, the best answer I can come up with is that we don't have a good way to express C++ code that allows you to operate on it. For instance, compile-time (or pre-processor, or whatever) reflection or a code DOM.
C++ badly needs one or both of these to be available to a developer to do meta-programming.
Then you could write something like this in your public MyClass.h:
#pragma pimpl(MyClass_private.hpp)
And then write your own, really quite trivial wrapper generator.
Someone will have a much more verbose answer than I, but the quick response is two-fold: the compiler needs to know all the members of a struct to determine the storage space requirements, and the compiler needs to know the ordering of those members to generate offsets in a deterministic way.
The language is already fairly complicated; I think a mechanism to split the definitions of structured data across the code would be a bit of a calamity.
Typically, I've always seen policy classes used to define implementation behavior in a Pimpl-manner. I think there are some added benefits of using a policy pattern -- easier to interchange implementations, can easily combine multiple partial implementations into a single unit which allow you to break up the implementation code into functional, reusable units, etc.
May be because the size of the class is required when passing its instance by values, aggregating it in other classes, etc ?
If C++ did not support value semantics, it would have been fine, but it does.
Yes, but...
You need to read Stroustrup's "Design and Evolution of C++" book. It would have inhibited the uptake of C++.