Friends We want to explicitly grant access to a function that isn t a member of the current class/struct. This is accomplished by declaring that function (or an entire other struct) as friend inside the class/struct declaration.
This wouldn t work without the previous declaration of X This wouldn t work without the previous declaration of y Also serves as prototype for the global function h Also serves as prototype for the global function g
Why do we need to declare g and h as friends of X?
Why do we need to declare Z as friend of X?
The fine print
CONCLUSION Forward (a.k.a. incomplete) declarations are needed only when we declare member functions as friends. They are not needed for global functions or entire structs/classes.
text Conclusion on friends In a pure OOL, only member functions would have access to the private members friend is introducing an exception C++ is a hybrid object-oriented language, not a pure one, and friend was added to get around practical problems that crop up. It s fine to point out that this makes the language less pure, because C++ is designed to be pragmatic, not to aspire to an abstract ideal.
Nested friends A nested class is a member of the enclosing class, and as such has unrestricted access to all other members (private or public). The members of an enclosing class have no special access to members of a nested class. This was only introduced in C++11 standard! The text example C05:NestFriend.cpp is pre- C++11, that s why the nested class is declared as friend. This was the case since the 1980s.
Nested friends Example not in text
Nested friends Example not in text
Skip the text example C05:NestFriend.cpp except the following useful tidbit
What does this function do? The Standard C library function memset( ) (in <cstring>) is used for convenience in the program above. It sets all memory starting at a particular address (the first argument) to a particular value (the second argument) for n bytes past the starting address (n is the third argument). Of course, you could have simply used a loop to iterate through all the memory, but memset( ) is available, well-tested (so it s less likely you ll introduce an error), and probably more efficient than if you coded it by hand.
Example not in text (it works in C, too) Beginning address of memory block to fill Character (Byte) to fill with How many positions to fill
Extra-credit quiz
Individual work for next time: Rewrite the code in Public.cpp and Private.cpp with class instead of struct. Further modify the member functions in both programs to print all the data members in their class. Enter and run the modified programs in the IDE of your choice.
QUIZ Why are friends impure?
QUIZ What are the 3 types of entity a class can befriend in C++? Which one requires a fwd. declaration and which ones don t?
solution Forward (a.k.a. incomplete) declarations are needed only when we declare member functions as friends. They are not needed for global functions or entire structs/classes.
QUIZ Do nested structs automatically have access to the private members of the outer struct?
Object layout Within a particular access block (a group of declarations delimited by access specifiers), the variables are guaranteed to be laid out contiguously, as in C. However, the access blocks may not appear in the object in the order that we declare them.
Object layout Although the compiler will usually lay the blocks out exactly as you see them, there is no rule about it, because a particular machine architecture and/or operating environment may have explicit support for private and protected that might require those blocks to be placed in special memory locations. The language specification doesn t want to restrict this kind of advantage.
Access specifiers are part of the structure and don t affect the objects created from the structure. All of the access specification information disappears before the program is run; generally this happens during compilation. In a running program, objects become regions of storage and nothing more. If you really want to, you can break all the rules and access the memory directly, as you can in C. C++ is not designed to prevent you from doing unwise things. It just provides you with a much easier, highly desirable alternative.
The class In the original OOP language, Simula-67, the keyword class was used to describe a new data type. This apparently inspired Stroustrup to choose the same keyword for C++, to emphasize that this was the focal point of the whole language: the creation of new data types that are more than just C structs with functions. However, the use of class in C++ comes close to being an unnecessary keyword. It s identical to the struct keyword in absolutely every way except one: class defaults to private, whereas struct defaults to public.
A note on style vs. Public first Private first
Some programmers like it, for others it is overkill: Because mx is already hidden in the scope of Y, the m (for member ) is unnecessary. However, in projects with many global variables (something you should strive to avoid, but which is sometimes inevitable in existing projects), it is helpful to be able to distinguish inside a member function definition which data is global and which is a member.
QUIZ Write the interface for a class called Quadratic, with 4 double members: the 3 coefficients a, b, c, and the determinant det. What member functions would you propose? Make sure you use access specifiers!
Read Modifying Stash to use access control
Handle classes Access control in C++ allows you to separate interface from implementation, but the implementation hiding is only partial. The compiler must still see the declarations for all parts of an object in order to create and manipulate it properly. Including the private ones
Handle classes Can we put the private part of a class in a separate file? A: Yes! This solution is called a Handle class.
Example projects where we don t want the implementation visible to the client programmer: The library header file may show proprietary info. that the company doesn t want available to competitors. Security (e.g. an encryption algorithm) don t want to expose any clues in a header file that might help people crack the code. Library is used in a hostile environment, where the programmers will try to directly access the private components anyway, using pointers and casting.
Solution: Place public interface in header file, and move all private stuff in implementation (.cpp) file. This technique is called handle classes or the Cheshire cat everything about the implementation disappears (from the header file) except for a single pointer, the smile.
A.k.a.: incomplete type specification fwd. declaration (as in friends!) class prototype (as for functions)
The private structure body is hidden away in the implementation file: Nested struct Etc.
This is the layout of the project, with the 2.cpp files and one header:
End-of-chapter problem: solution
I changed this value! See console messages from building on next slide
Console messages from building (compiling + linking) the project in MSVS Initial build Build after modifying only implementation file
Homework for chs.4+5 Provided on our webpage --> agapie.net Due Mon., March 5 Please hand in a hard-copy, do not email! EOL 2