10 Classes: A Deeper Look, Part 2 530
10.1 Introduction 531
10.2 const (Constant) Objects and const Member Functions 531
Chapter 10 pages 532 -- Const
If a const object is declared and initialized can it be changed later in the program?
NO.
Chapter 10 pages 532-533 -- const Objects and const Member Functions
Why can compilers perform optimizations on constants that it cannot perform on variables?
What kind of optimizations does it perform?
Basically it can avoid storing them in RAM and keep them inside the CPU. Saves a little space and a little time. Small constants can even be placed inside special operations in the program.
Chapter 10 pages 532 -- constructors
If the constructor must be allowed to modify data even in a const object, could this be exploited to affect program behavior? (crack?)
No. Constructors provide the initial values, and the "const" makes sure it can not be changed. Once constructed.... constructors can not be used on the same object again.
Chapter 10 pages 537 -- Member Initializers
Why is addIncrement() defined in the header file in figure 10.4, but the other functions are not?
Because it is short and so a good function to "inline".... I guess.
Chapter 10 pages 537 -- Constants
In fig 10.5, am I right in saying that int c and i are normal variables, but the cout function is const, where:
void Increment::print() const
No.... they are c and i are parameters of the constructor for Increment. They are used to initialize the data in the object: count and increment respectively.
The variable count and increment are used in the print() function.... which does not change them -- and so is declared as a "const" function.
10.3 Composition: Objects as Members of Classes 541
Notice the UML notation.
10.4 friend Functions and friend Classes 548
Explain friends
When class A declares it has a friend then that friend has access to the private data and
private functions. As far as friends are concerned -- everything is public.
Friend function also do not have an implicit "this" pointer to reference. Access to the object has to be explicit. Compare
object.memberFunction( data )
friendFunction( object, data )
A class has to grant friendship to other classes and functions. They can not get access without written permission in the class itself.
Chapter 10 pages 548-549 -- friend class vs friend function
What is the differences between friend function and friend class
A friend function is a single function with privileged access to private data.
A friend class is has a whole slew of of functions all of which can foul up an objects personal storage.
When to use friends
(1) Don't. (2) Experts only -- it makes sense for some operators like "<<" and ">>"
to be permitted access to private features and so be friends.
Chapter 10 pages 548 -- friend classes
The book says friend classes can be good for performance. How is that so?
I'm not sure I believe this. I think they mean that the friend can grab the data it wants and do things to it with out using a function to access it. This may save a few micro-seconds of CPU time, but you will pay for it with a few hours of debugging time.
10.5 Using the this Pointer 552
Chapter 10 pages 553 -- the "this" pointer
what is the "this" pointer used for?
When are this pointers useful?
They have two main purposes that I can recall. First you can send them to other objects so that the other object can reply to you. You can also return *this as the value of a function.... see later.
The main use of this is rather like sending your EMail address to someone else so that they can send you messages back. So, for example, you an object that wants to react when the user does something with the mouse in a window might do this
window -> subscribeMouseEvent(this);and the operating system will store the address
Listener * listener = thisand send it messages like
listener->mouseDown(x,y);This is a common pattern (the "Observer Pattern") when writing GUIs.
The word 'this' in C++ is a pointer -- the address of an object of this class.
The expression '*this' follows the pointer to the object -- it dereferences it.
The dot operator when applied to an object extracts one member from it, so (*this).x extracts the x for the current object.
This is such a common operation that C/C++ provides short hand "p->x" means the same as "(*p).x" for all pointer p to objects containing data x.
Chapter 10 pages 554 -- 'this' Pointer and cascaded calls
How can "this" pointer be used to enable cascaded function calls?
Suppose that a member function f() in a class ends with
return this;then if we have an object x that is an instance of this class then
x.f()returns the address of the object and we can use it with another function g() say:
x.f()->g()
In the book, the function f() is set up to return a reference to (*this) and so we can write
x.f().g()and if g() returns a reference to *this....
x.f().g().h()......can be written.
This is a common idiom in several languages and several GUI frameworks. On the other hand, some modern experts claim that code with many "cascades" signals the need to refactor the classes.
Chapter 10 pages 566 -- arithmetic overflow
What does arithmetic overflow do to the program?
It depends on the compiler, I think. It should, IMHO, abort the program. But in most cases the program continues with some unexpected values ... for example if you repeatedly add 1000 to an int it will end up being a negative number!
10.6 Dynamic Memory Management with Operators new and delete 557
Be very careful with these. Wrap them up in an object that knows
how to delete the storage it allocates with new.
Chapter 9 pages 506-510 -- destructors
Can you give me a good example of when destructors are used?
For each 'new' your program executes, it will need a 'delete'. Destructors provide a place to execute 'delete's. So if you have Dynamic Memory Management in a class... you'll need a destructor. If no storage is dynamic then.... no real need for a destructor.... for the moment. More on this later since destructors interact with Inheritance and with Polymorphism.
Chapter 10 pages 557-558 -- Dynamic Memory Management
Can you clarify what dynamic memory management is useful for?
We use "dynamic memory" a lot. It is used whenever we don't know how much data we need before the program starts running. If we can predict the amount of data needed we can let the compiler handle it and use normal declarations. The compiler gives as the data, as we declare it on a piece of memory called the stack. The compiler also removes the data when it goes out of scope.
Dynamic memory is allocated as the program runs. It is allocated by a "new" statement. It is removed by a "delete" statement. We need to make sure that (1) we delete data that we don't need any more to avoid memory leaks. (2) we need to grab enough space before we attempt to use it. The process of getting the data and deleting is called "Memory Management".
The "new" operator gets data from a place in memory called the heap and the "delete" command returns it to the heap. It is not as tidy as the stack. It is also under our program's control -- we need to be careful.
Quick example: If we need 100 objects of type Widget for a program we can use the stack with
Widget array [100].
But if we don't know until the user tells us how many Widgets we need, and the user inputs the size then we need
cin >> size;
Widget *pointer = new Widget [size];And later in the code we must have
delete []pointer;
I find these hard to write correctly so I avoid them or wrap them up in class.
Chapter 9 pages 506-507 -- Destructores
Can you further explain this function and when specifically it can be used.
It is called by the program when objects are about to vanish. You provide them if and only if there is dynamic memory to be tidied up.
Destructors -- take out the trash and recycle it for us.
10.7 static Class Members 559
Also known as class wide.
These belong to a class rather than each object in the class, they were
covered in the previous class
[ 05.html ]
we won't be covering, in cs202 the other uses. Static local variables in a function
were in CS201 and will be in cs320 again. Static global variable are not used as much these days....
look it up when you meet one in legacy code.
10.8 Data Abstraction and Information Hiding 565
A powerful idea that works.
Chapter 10 pages 565-568 -- Abstraction and Information Hiding
What is the concept of data abstraction and how does abstract data types (ADTs) work?
Data abstraction means that the data in an object or class can only be accessed by using special functions to access and set the data. The functions act as an interface to the data.
An ADT was the idea before objects. It is a computer version of an abstract algebra! An ADT has a collection of data which it hides away and a collection of operations that manipulate them.
10.8.1 Example: Array Abstract Data Type 566
10.8.2 Example: String Abstract Data Type 567
10.8.3 Example: Queue Abstract Data Type 567
10.9 Container Classes and Iterators 568
More on iterators later.
10.10 Proxy Classes 568
Chapter 10 pages 570 -- Forward class declaration
when would forward class declaration be used and in a little more detail on how?
You use a forward definition when you need to refer to a class by name but don't want to reveal its details. Once the compiler sees
class Widget;it knows that it is OK for your code to declare
Widget *widgetPtr;however it won't be happy with a normal declaration of an object until it sees the amount of data in the class.
Chapter 10 pages 568 -- proxy classes
when would you create a nested proxy class or use it?
Not used very often these days .... not in CS202.
Chapter 10 pages 531-572 -- Proxy Classes
Can you elaborate on the functionality of a Proxy Class please?
A Proxy stands in for a real object. Proxies have the same functionality as some other object, but they hide the data. They it should have the same function names, and each function in the proxy calls the equivalent function in the real object.
(You can download
[ Proxy.dia ]
if you want to see code inside the functions).
Notice: The proxy however does not have real data -- this is kept elsewhere. The proxy creates and deletes a single pointer to a real object. It is responsible for the "real" object's existence -- hence the destructor and the black diamond (composition) between the Interface and the Implementation.
Result, client code can use the implementation without knowing anything about the real object. It could even be on a different computer!
Chapter 10 pages 568-572 -- Proxy Classes
What is the purpose for having a proxy class if the private data is already hidden from being tampered with. Could you explain a time when a proxy class is needed
We can give our client programmers the Interface as their API (Application Programmer Interface) and use separate compilation to hide what the details of the real data. Not only is the program unable to tamper with the private date, even the programmer is unable to read what is hidden. This is a strict form of information hiding that was proposed and argued for by Parnas [ David_Parnas ] in the 1970's and 80's. The trend toward open source and agile code based methods has made people a lot less dogmatic.
These days we use proxies to hide something that might vary in the future, but not to hide the source code form our colleagues.
Chapter 11 pages -- Operation overloading -- Next time
Can you explain the use for overloading operators such as "+", "-", and "="?
Next time.
Chapter 10 pages 583 -- Functions -- Next time
could you go over operators as member functions and global functions ??
This is in chapter 11, not 10, and we will tackle it next time.
Exercises
Based on chapter Input above. Examples: take UML and code in C++,
take given C++ and draw UML, ...
Lab
Same as Monday:
[ lab03.html ]
. . . . . . . . . ( end of section CSci202 Computer Science II, Session 06, More about C++ classes) <<Contents | End>>
(Next): Deriving classes and Inheritance
[ 07.html ]
Project 2 is due at the start of the 8th class, next week.
Abbreviations