


Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An overview of various concepts in c++ classes, including header files, constants, static members, information hiding, pointers, and inheritance. Topics covered include the use of header files to prevent duplicate inclusions, defining constants using #define and const, static class members, and the principle of query functions being defined as const. The document also discusses the concept of access specifiers (public, protected, private) and their impact on derived classes, as well as the use of pointers and references with inheritance.
Typology: Study notes
1 / 4
This page cannot be seen from the preview
Don't miss anything!



//your declarations
─ Used for system header files
─ May check include search path if not found there ─ Used for your own header files
#define BUFFERSIZE 100 ─ BUFFERSIZE cannot be used as a variable const int buffersize = 100; const ClassName aConstantObject; ─ What if we invoke an operation on a constant object that can change its data members? aConstantObject.setValue(); ─ Only const member functions can be invoked! int getValue() const {…} //Hi, I will not change data members! const int getValue() {…}//The function’s return value is const.
─ Meaningless for built-in types ─ But meaningful for user-defined types: getStudentRecord().setName() Principle: Query functions (such as getValue()) should always be defined as const. Principle: Passing by reference or by pointer should always be defined as constant if you do not change it. Constant passing by reference is better than passing by value. ─ int compare( const Student& s1, const Student& s2) Note: Constant data members of a class can only be initialized through the member initialization list of the constructor. ─ Student(string name): _studentName(name) {…}
// In Counter.h class Counter{ public: Counter(){ num++;} static int getNum() { return num; } //Can only refer to static member num private: static unsigned num; //one copy per class string name; //one copy per object };
}; // In Counter.cpp unsigned Counter::num = 0; // Defines and allocates num
─ C++ has a standard string class. But what if IBM also developed a string class?
namespace IbmStringPackage { class string{ //IBM implementation of string class
p g } }
─ (1) Use IbmStringPackage::string as the class name ─ (2) Declare “using namespace IbmStringPackage;” first, then use string as class name. But in this case, you cannot delare “using namespace std;”.
int max( int, int ); double max( double, double );
class A{ public: //data and functions needed by clients (public interface). protected: //data and functions needed by derived classes. private: //data and function needed by class A only. };
─ Client programs do not need them. Only for implementation. ─ They are subject to future change. ─ For private data, client programs may misuse them and cause inconsistency
─ Needed by derived classes. Derived classes are trusted, but client programs are not.
class DerivedClassName: access_specifier BaseClassName{ //…… }
─ Default (no access_specifier) = private
public protected private
public public protected private
protected protected protected private
private X X X
─ In some cases when you want to operate on data with more stringent requirements, you do not want to inherit the entire interface of the base. ─ For example, suppose you have a Dequeue class that contains operations to insert and delete elements at either end of the queue. Now you want to implement a Queue class, which one can only insert on the left and delete on the right. class Dequeue{ public: void insertL( int );
class Queue: private Dequeue{ public:
─ Note: “using” restores insertL() and removeR() public; others remain private.
void insertL( int ); void insertR( int ); int removeL(); int removeR(); protected: //internal data structure };
public: using Dequeue::insertL; using Dequeue::removeR; };
─ In some cases when you only want to inherit the implementation of the operations in the base class, and you do not want to inherit any interface at all. ─ For example, suppose you have a Dequeue class that contains operations to insert and delete elements at either end of the queue. Now you want to implement a stack class, which one can only insert on the left and delete on the left. In addition, you want to use new operation names such as push and pop. class Dequeue{ public:
class Stack: private Dequeue{ public: void push ( int x )
─ “Using” must keep the access level the same as the base.
void insertL( int ); void insertR( int ); int removeL(); int removeR(); protected: int _left; int _right; };
{ insertL(x); }; int pop() {removeL(); }; bool full() { return _left == _right;} protected: using Dequeue::_left; using Dequeue::_right; };
void foo(){ Manager m, *mPtr; Employee e, *ePtr;
ePtr = &m; // OK mPtr = &e; // Error. An employee may not be a manager. }
─ Derived class inherits function and data members from base class ─ Derived class may add additional function or data members ─ Derived class may override inherited function members with new methods
─ Invoke function whose formal parameter is of (reference or pointer) to class C with actual parameter of (reference or pointer to) class derived from C.
─ Manager and employee
int main(void){ Employee anEmployee(“John”, “Doe”, 235); Manager aManager(“Charles”, “Howell”, 235, 3);
anEmployee.print(cout); // invokes Employee::print() aManager.print(cout); // invokes Manager::print()
Employee* ePtr = &aManager;
─ Operations are over-ridden with new methods. ─ E.g., print is an operation; Employee::print and Manager::print are methods.
p y g ; ePtr->print(cout); // invokes Employee::print() }
void myPrint( Employee& empl ){ empl.print(cout); };
int main(void) { Employee anEmployee(“John”, “Doe”, 235); Manager aManager(“Charles” “Howell” 235 3);
─ Answer: Employee::print() ─ Reference is similar to pointer
Manager aManager( Charles , Howell , 235, 3);
myPrint(aManager); }