sizeof()

a char* pointer's size is fixed at 4 bytes (on 32-bit system, and double it on 64-bit) and is independent of the volume of data being pointed to.

declaring a friend of a class

a friend keyword used in external classes of functions have access to data declared private.

e.g. using the friend keyword to allow an external function to access to private data members.

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
#include <iostream>
#include <string>
using namespace std;

class Human
{
private:
friend void DisplayAge(const Human &person);
int age;
string name;

public:
Human(string humanName, int humanAge)
: name(humanName), age(humanAge) {}
};

void DisplayAge(const Human &person)
{
cout << person.age << endl;
} // no ; behind right brace for a function but class does

int main()
{
Human ManTom("Tom", 20);
DisplayAge(ManTom);

return 0;
}

enumeration

Enumerated type is a user defined data type also named as enumerator type.

syntax
1
2
3
4
enum enumName
{
value1,value2,...,valueN
}urName

Defining enumerator type enumName, meanwhile, define it's variable urName. Otherwise, using it as follow:

syntax
1
2
3
4
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

Use :: for scoped enumerations

quote here: other scope resolution operator usages

1
2
3
4
5
6
7
8
9
enum class EnumA{
First,
Second,
Third
};

int main() {
EnumA enum_value = EnumA::First;
}

differences of enum and enum class

quote here: Why is enum class preferred over plain enum?

C++ has two kinds of enum

  • enum class
  • plain enum
what's the difference of the two?
  1. enum class - enumerator names are local to the enum and their values are not implicitly convert to other types (like other enum or int)
  2. plain enum where enumerators are in the same scope as the enum and their values implicitly convert to integers and other types.
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
enum Color { red, green, blue };                    // plain enum 
enum Card { red_card, green_card, yellow_card }; // another plain enum
enum class Animal { dog, deer, cat, bird, human }; // enum class
enum class Mammal { kangaroo, deer, human }; // another enum class

void fun() {

// examples of bad use of plain enums:
Color color = Color::red;
Card card = Card::green_card;

int num = color; // no problem

if (color == Card::red_card) // no problem (bad)
cout << "bad" << endl;

if (card == Color::green) // no problem (bad)
cout << "bad" << endl;

// examples of good use of enum classes (safe)
Animal a = Animal::deer;
Mammal m = Mammal::deer;

int num2 = a; // error
if (m == a) // error (good)
cout << "bad" << endl;

if (a == Mammal::deer) // error (good)
cout << "bad" << endl;
}
Another Example
1
2
enum class Animal{Dog, Cat, Tiger};
enum class Pets{Dog, Parrot};

Here we can not mix Animal and Pets values.

1
2
Animal a = Dog;       // Error: which DOG?    
Animal a = Pets::Dog // Pets::Dog is not an Animal
Further
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
#include <iostream>
using namespace std;

enum class Color {
Red,
Green,
Blue
};

void printColor(Color color) {
switch (color) {
case Color::Red:
cout << "The color is red." << endl;
break;
case Color::Green:
cout << "The color is green." << endl;
break;
case Color::Blue:
cout << "The color is blue." << endl;
break;
default:
cout << "The color is unknown." << endl;
break;
}
}

int main() {
printColor(Color::Red);
printColor(Color::Green);
printColor(Color::Blue);
return 0;
}

difference between <string> and <string.h>

  • <string.h> contains old functions like strcpy, strlen for C style null-terminated strings.
  • <string> primarily contains the std::string, std::wstring and other classes.

All in one

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
#include <iostream>
#include <string.h>
using namespace std;

union SimpleUnion
{
int num;
char alphabet;
};

struct ComplexType
{
enum DataType
{
Int,
Char
} type;

union Value
{
int num;
char alphabet;
Value(){};
~Value(){};
} value;
};

void
DisplayComplexType(const ComplexType &obj)
{
switch (obj.type)
{
case ComplexType::Int:
cout << "unions contain number is " << obj.value.num << endl;
break;
case ComplexType::Char:
cout << "unions cantain number is " << obj.value.alphabet << endl;
break;
}
};
int main()
{
SimpleUnion u1, u2;
u1.num = 1000;
u2.alphabet = 'a';
cout << "sizeof(u1) containing integer " << sizeof(u1) << endl;
cout << "sizeof(u2) containing character " << sizeof(u2) << endl;

ComplexType myData1, myData2;
myData1.type = ComplexType::Int;
myData1.value.num = 1000;

myData2.type = ComplexType::Char;
myData2.value.alphabet = 'A';

DisplayComplexType(myData1);
DisplayComplexType(myData2);

return 0;
}
Analysis

The sample demonstrates that sizeof() the union objects u1 and u2 returns the same amount of memory reserved for both objects, notwithstanding the fact that u1 is used to hold an integer and u2 a char, char being smaller than an int. This is because the compiler reserves the amount of memory for a union that is consumed by the largest object it contains.