Little notes
student.Person::display();
Derived Class with resource copy constructor, please refer here.
student.Person::display();
Derived Class with resource copy constructor, please refer here.
operator dataType() const;If the Student(int) constructor were absent, the compiler could not convert 1234 to a Student and would reject the assignment expression. However, if our class declaration had a Student(long long) constructor, the compiler could convert 1234 to 1234LL, then convert 1234LL to a Student data type, and finally assign the right Student operand to the left Student operand.
example: operator int() const;
In our case, the compiler fails to find an exact, promoted,
or standard-conversion match for any argument-parameter pair,
and searches the single argument constructors for a derived data
type conversion match. The compiler inserts the
constructor code to convert 1234 to a
Student and then calls the assignment
operator that receives a Student as
its right operand. That is,
harry = 1234; // calls operator=(const Student& Student(1234))
To comprehend above please refer more detail
Resources
Resources include dynamic memory and files. These collections of information contain data that is stored outside the memory allocated to an object. An object keeps track of its resources through instance variables that hold the addresses of the resources. Such instance variables include
To enable deep copying, we overwrite the compiler defaults for two member functions:
A copy constructor declaration takes the form
Identifier ( const Identifier& );
Assignment Operator
The assignment operator is an operator that copies data from an existing object into an existing object. The compiler calls this operator whenever the compiler encounters an expression of the form
identifier = identifier where identifier is the name of an object.The form of an assignment operator declaration is
Identifier& operator=(const Identifier&);No Copies Allowed
In certain applications, it may be wise to avoid the making copies or assignments altogether. To prohibit the copying and the assigning of objects, we declare the copy constructor and the assignment operator as private members. For example,
Student operator+(const Student &student, char grade) {
Student modified = student;
modified += grade; // calls += operator
return modified;
}
Student operator+(char grade, const Student &student) {
return student + grade; // calls operator+(const
// Student&, char)
}
friend type helper(...);
in .h file
friend int operator==(const Student&, const Student&);
in .cpp file
int operator==(const Student& lhs, const Student& rhs) {
return lhs.no == rhs.no &&
strcmp(lhs.grade, rhs.grade) == 0;
}
Friend Classes (Optional)
A class can grant access to its own private members to all of the member functions of another class. A class friendship declaration takes the form
friend class Identifier;where Identifier is the name of the class that is to have private access privileges.
class student{
...
public:
...
friend class Administrator;
}
Candidates for Overloading
We may overload the following operators (amongst others):
We may NOT overload the following operators
Type operator++(int) or Type operator--(int)
The int type in the parameter list
distinguishes the post-fix operator from its pre-fix
counterpart.
Student Student::operator++() {
for (int i = 0; grade[i] != '\0'; i++)
if (grade[i] == 'F') grade[i] = 'D';
else if (grade[i] != 'A') grade[i]--;
return *this;
}
Student Student::operator++(int) {
Student s = *this; // save the original
++(*this); // call the pre-fix operator
return s; // return the original
}
Manipulator | Effect |
fixed | display floats in fixed-point format |
scientific | display floats in floating-point format |
left | left justify |
right | right justify |
flush | flush the output buffer |
endl | send end of line and flush |
setprecision(int) | set number of digits output |
setfill(int) | set fill character |
setbase(int) | set base for int output |
setw(int) | set field width for next output only |
display(); // calls member function from inside a member function
::display(); // calls global function from inside a member function
Variables and objects stored in dynamic memory can survive until the program terminates if necessary. Their lifetime only ends when the program explicitly deallocates their dynamic memory. Note that, unlike variables and objects in static memory, those in dynamic memory do not go of out scope at the closing brace of the block within which they have been defined.
struct Student {
int no; // student number
char grade[14]; // grades
};
struct Student harry;
to access harry's student number, we write
harry.no;
to get address of harry's student number, we write
&harry.no;
//&harry.grade[0];
We retrieve the address of a non-array member using the address of operator (&)
char str[] = "This is OOP244";
char* s;
s = &str[8]; // points to the first 'O' in OOP244
cout << *(s + 3) << endl; // displays 244
New Style Casts
The new style casts are both more specific and much easier to spot. Their syntax includes the letters _cast, which makes searching more straightforward. The casts are in template function form, where the variable or object to be cast is passed as the function argument and the destination type is passed as the template argument. There are four distinct categories of casts:
static_cast ( minutes )
const_cast (&p)(Polygon is a class here)
Re-Interpret Cast
A re-interpret cast converts a value between unrelated data types such asinteger to pointer type, pointer to unrelated pointer type
For example,
// Re-Interpret Cast
// reinterpret.cpp
// Nov 21 2005
#include
using namespace std;
int main( ) {
int* p;
int x = 0x00ff00;
p = reinterpret_cast( x ); // New Style Cast
cout << hex << p << endl;
return 0;
}
void divide(int a[], int i, int n, int divisor) {
if(i <>= n)
throw "Outside array bounds";
else if(divisor == 0)
throw divisor;
else
a[i] = i / divisor;
}
int main() {
bool keepgoing = true;
int a[MAX] = {1,2,3,4,5,6,7,8,9,10}, index,
divisor;
do {
try {
cout << "Index: "; cin >> index;
cout << "Divisor: "; cin >> divisor;
divide(a, index, MAX, divisor);
cout << "a[index] = " << class="high">} catch(const char* msg) {
cout << keepgoing =" false;" class="high">} catch(int value) {
cout << "Zero divisor" << class="high">}
} while (keepgoing);
return 0;
}
All of the code within the try
block is executed repeatedly unless an exception is thrown by
any of the statements within the block. If an exception is
thrown, any remaining code within the try block is skipped and the code in the first
catch block that receives a type
matching the type of the thrown exception is executed. If
an exception is thrown and no match is found at any point in the
program, the program calls std::terminate(), which terminates
execution.
bool Box::operator==(const Shape& s) const {
return hght == dynamic_cast(s).hght &&
wdth == dynamic_cast(s).wdth &&
dpth == dynamic_cast(s).dpth;
}
Answer:
The cast of the reference to a Shape to a reference to a Box is necessary to enable access to the size instance variables of the Box object. We call this a dynamic cast. Without this cast, the compiler would generate an error to the effect that the size variables are not members of the Shape class:
bool Box::operator==(const Shape& s) const {bool Box::operator==(const Box& s) const { // ERROR does not define
return hght == s.hght && // ERROR hght is not a member of s
wdth == s.wdth && // ERROR wdth is not a member of s
dpth == s.dpth; // ERROR dpth is not a member of s
}
On the other hand, receiving a reference to a Box object directly would accept the definition
An abstract class identifies the properties that need to be defined through pure virtual functions. For instance, if a Shape has a volume, then the abstract Shape class would include a pure virtual function for volume.
The term interface refers to an abstract class that contains no data members.
and / or
Pure Virtual Functions
A pure virtual function is a virtual function that has form but no implementation. The declaration of a pure virtual function takes the form
virtual type identifier(parameters) = 0;
Virtual Inheritance
To avoid duplication of the instance of the base class, the Box and ColouredShape object can share the same Shape object.
// A Box
// Box.h
// Jun 9 2007
#include "Shape.h"
class Box : virtual public Shape {
int hght;
int wdth;
int dpth;
protected:
void displayDetails() const;
public:
Box(const char* s, int h, int w, int d);
virtual void display() const;
};
Read more details https://cs.senecac.on.ca/~btp300/pages/content/minhe.html
In object-oriented programming languages with multiple inheritance and knowledge organization, the diamond problem is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If a method in D calls a method defined in A (and does not override the method), and B and C have overridden that method differently, then from which class does it inherit: B, or C?
Please refer to http://en.wikipedia.org/wiki/Diamond_problem
Odd Test
The & operator provides a simple way to check if an integral value is odd: that is, whether its least significant bit is 1.
odd = value & 1
odd has the value 1 if value is odd, 0 if value is even.
Note that sizeof() takes a type, while sizeof takes a variable, object or expression. With some compilers, the two operators are interchangeable.
For normal usage, we may add the keyword auto (for automatic) to the definition
auto int local = 2; |
Since this is the default for any function parameter or any variable defined within a block, we seldom see this keyword in practice.
For very frequent usage, we add the keyword register to the definition
register int local = 2;
static int local = 2;
External Linkage
A variable of static duration with external linkage can be shared by several modules. The compiler allocates memory for the variable in one module and the linker allows all modules access to that memory location. Each reference to the variable accesses the same memory location, regardless of the module from which the reference is made. To identify external linkage, we add the keyword extern to the declaration
C Conversion Specifiers
The C language conversion specifiers for the int type used in calls to scanf() are
Specifier | Input Value | Argument | Default Conversion |
%c | cc...c | char* | one or more characters |
%d | [-|+]dd...d | int* | signed decimal |
%i | [-|+][0[x]]dd...d | int* | signed integer |
%u | [-|+]dd...d | unsigned* | unsigned decimal |
%o | [-|+]dd...d | unsigned* | unsigned octal |
%x | [-|+][0x]dd...d | unsigned* | unsigned hexadecimal |