-
Notifications
You must be signed in to change notification settings - Fork 0
/
C++_notes.txt
executable file
·256 lines (211 loc) · 9.95 KB
/
C++_notes.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
C++ PRIMER:
CHAPTER 7:
Pg 343
References Vs Pointers [C++ Primer Pg 343]
- Useful for OPERATOR OVERLAODING
References - alias to objects;
Once initialized CANT be made to refer another object;
References - NOT correct to initialize to ADDRESS of object;
But can define POINTER REFERNCE.
int *i = &j;
int *&a = i;
Pg 346
2) When Arrays are passed, -> Passed as a Pointer.
So size of array is not PART of its parameter type. Hence size has to be passed to the function as well
3) Ellipses SUSPEND type-checking
4) Global VS Return Arguments (Communication between function)
Global -> Reusing the funciton becomes difficult
-> Even local changes need full understanding of the program.
-> Recursion and threading becomes tough
5) LINKAGE DIRECTIVES -> EXTERN [Pg 364]
Tell that the specific function is in a different lang and use its NAMING CONVENTIONS/ PARAMETER passing etc. eg. extern C
6) Function name is not part of its type.
function type -> determined by Return type and Argument list
--------------
CHAPTER 8: SCOPE & LIFE TIME
1) Type Safe Linkage: [Pg 398]
Type & no of function parameters are encoded in function name.
2) PLACEMENT NEW [Pg 417]
Object will be created in MEMORY that is already allocated
--------------
CHAPTER 9: OVERLOADING: - Pg 452
1) Function Overloading can have ONE EXTERN function
void fn(int);
void fn(double);
void (*pf) (int) = &fn
2) Viable functions
CHAPTER 11: EXCEPTIONS
1) Stack Unwinding:
Order in which catch clauses are examined
------------------------------------------------------------------------------------------------
Deitel C++:
srand - to avoid pseudo random numbers. srand(TIME)
character array can be treated as strings
function overloading taking only the method arguments for differentiating, not the return values
when different functionality has to be carried out
Templates:
when same functionality has to be done
Template <class T>
T max(T a, T b)
{
if (a < b)
return b)
}
Passing Array to a function:
Always done through Call by Reference.
So changing the contents of passed array changes the original array
A constant pointer has to be initialized at declaration itself
int x,y
int * const ptr = &x; //ptr always points to the same memory location but the value at that memory location can change.
* ptr = 7;
ptr = & y; //ERROR
CANNOT DEREFERENCE A VOID* POINTER
FUNCTION POINTER: pG 303
http://www.newty.de/fpt/intro.html
return_type (*fn_name[size])(args) = {fn1, fn2, fn3 ... fnSize};
(*fn_name[choice])(choice)
-------------------------------------
USe of FRIENDs violates ENCAPSULATION of a class
Pg 408
THIS POINTER:
- Each object maintains a pointer to itself
- PREVENT self assignment during Operator overloading [Assigning an object t o itself]
------------------------------------
OPERATOR OVERLOADING: Pg 456
. , .*, ::, sizeof, ?: CANNOT BE OVERLOADED
OVERLOADING UNARY OPERATORS:
- non static member function with NO arguments OR
non member function with ONE argument
OVERLOADING BINARY OPERATORS:
- non static member function with ONE arguments OR
non member function with TWO arguments. (ONE of which must be a CLASS object/Reference to a CLASS object)
int String::operator<(const String &right) const
{ return strcmp(sPtr, right.sPtr) >= 0;}
------------------------------------
VIRTUAL FUNCTIONS: Pg 538
B *b;
D d;
b = &d;
b->print(); //DYNAMIC BINDING
d.print(); //STATIC BINDING
When you have a base class and a derived class, if you want a specific implementation of method in the base
class, you override it by giving a specific implementation in the derived class.
Both of the functions will be having the same name.
Base Class: Animal
Method: eat() {"eat any food"};
Dervided Class: Cow, Cat
Method: eat() {"eat grass"}, eat() {"eat cat"}
If we have a function xyz(Animal* ani){ ani->eat()},
If we have a COMMON FUNCTION for all dervided classes, then if we want to call a specific implementation at run time,
we should make the function virtual.
PURE VIRTUAL FUNCTION:
you want the base class to present only an interface for its derived classes. That is, you don’t want anyone to actually create an object of the base class, only to upcast to it so that its interface can be used. This is accomplished by making that class abstract, which happens if you give it at least one pure virtual function . You can recognize a pure virtual function because it uses the v i r t u a l keyword and is followed by = 0. If anyone tries to make an object of an abstract class, the compiler prevents them.
VIRTUAL DESTRUCTORS:
If a class has virtual functions, make the DESTRUCTORS virtual. so that derived class may contain destructors which has to be called properly.
IMP TIC++:
Each destructor knows what its class is derived from , but not what is derived from it.
The problem occurs when you want to d e l e t e a pointer of this type for an object that has been created on the heap with n e w. If the pointer is to the base class, the compiler can only know to call the base-class version of the destructor during d e l e t e. Sound familiar? This is the same problem that virtual functions were created to solve for the general case. Fortunately, virtual functions work for destructors as they do for all other functions except constructors
class Base1
{
public:
~Base1() { cout << "~Base1()\n"; }
};
class Derived1 : public Base1
{
public:
~Derived1() { cout << "~Derived1()\n"; }
};
class Base2
{
public:
virtual ~Base2() { cout << "~Base2()\n"; }
};
class Derived2 : public Base2
{
public:
~Derived2() { cout << "~Derived2()\n"; }
};
int main()
{
Base1* bp = new Derived1; // Upcast
delete bp;
Base2* b2p = new Derived2; // Upcast
delete b2p;
}
P U R E V I R T U A L D E S T R U C T O R S - Pg 722 TIC++
------------------------------------
TEMPLATES: Pg 606 Deittel
SYNATX: template<class T> ;
template<class T, class U>
template<class T>
void print(T *array, const int c)
{
for(int i=0;i<c;i++)
cout<<array[i];
}
Class templates are PARAMETERIZED TYPES - Pg 609
------------------------------------
EXCEPTION HANDLING TIC++ PART 2 Pg 373
throw myerror(“something bad happened”);
myerror is an ordinary class, which takes a char* as its argument.
------------------------------------
FILE IO Pg 653 Deitel
IOS
ISTREAM
IFSTREAM
OSTREAM
OFSTREAM
iostream -> in both I&O
FSTREAM - from IOSTREAM
main()
{
ofstream outF("a.txt", ios::out);
if(!outF)
exit(1); //ERROR
outF<<"Hi Whats up";
ifstream inF("a.txt", ios::in);
if(!inF)
exit(1);
while( inF>>acount>>name>>balance)
}
------------------------------------
NAME HIDING
if Base declares a member function f(double x), and Derived declares a member function f(char c) (same name but different parameter types and/or constness), then the Base f(double x) is "hidden" rather than "overloaded" or "overridden" (even if the Base f(double x) is virtual).
http://bojolais.livejournal.com/222428.html
Overloading and name hiding in C++
In a phone conversation with Brad last night, he told me about a strange problem he's encountered in his new C++ job. Granted, it's probably no big deal to people with extensive C++ experience, but to those of us who live in managed code worlds, this seemed strange.
In C++, when you have a class with an overloaded method (member function, whatever you want to call it), and you then extend and override that method, you must override all of the overloaded methods.
I understand the case where you have changed a method signature in a child class, thereby invalidating the established interface. In this case, though, it seems counterintuitive, since you're not changing the interface, but selectively overriding. Which is different.
For example:
class FirstClass
{
public:
virtual void MethodA (int);
virtual void MethodA (int, int);
};
void FirstClass::MethodA (int i)
{
std::cout << "ONE!!\n";
}
void FirstClass::MethodA (int i, int j)
{
std::cout << "TWO!!\n";
}
Simple class here with two methods (or one overloaded method). You want to override the two-parameter version, so you continue with the following:
class SecondClass : public FirstClass
{
public:
void MethodA (int);
};
void SecondClass::MethodA (int i)
{
std::cout << "THREE!!\n";
}
Now, when you use an instance of SecondClass, most Java or C# programmers might assume you can call:
int main ()
{
SecondClass a;
a.MethodA (1);
a.MethodA (1, 1);
}
However, the second call won't work, since the two-parameter MethodA is not visible. You can get a pointer and up-cast to FirstClass, but your SecondClass instance doesn't inherit the non-overridden methods directly.