當前位置:
首頁 > 知識 > 類型轉換運算符 運算符重載 operator new operator delete

類型轉換運算符 運算符重載 operator new operator delete

一、類型轉換運算符

必須是成員函數,不能是友元函數

沒有參數

不能指定返回類型

函數原型:operator 類型名();

C++ Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

#ifndef _INTEGER_H_

#define _INTEGER_H_

class Integer

{

public:

Integer(int n);

~Integer();

Integer &operator++();

//friend Integer& operator++(Integer& i);

Integer operator++(int n);

//friend Integer operator++(Integer& i, int n);

operator int();

void Display() const;

private:

int n_;

};

#endif // _INTEGER_H_

C++ Code

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

#include "Integer.h"

#include <iostream>

using namespace std;

Integer::Integer(int n) : n_(n)

{

}

Integer::~Integer()

{

}

Integer &Integer::operator ++()

{

//cout<<"Integer& Integer::operator ++()"<<endl;

++n_;

return *this;

}

//Integer& operator++(Integer& i)

//{

// //cout<<"Integer& operator++(Integer& i)"<<endl;

// ++i.n_;

// return i;

//}

Integer Integer::operator++(int n)

{

//cout<<"Integer& Integer::operator ++()"<<endl;

//n_++;

Integer tmp(n_);

n_++;

return tmp;

}

//Integer operator++(Integer& i, int n)

//{

// Integer tmp(i.n_);

// i.n_++;

// return tmp;

//}

Integer::operator int()

{

return n_;

}

void Integer::Display() const

{

cout << n_ << endl;

}

C++ Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#include "Integer.h"

#include <iostream>

using namespace std;

int add(int a, int b)

{

return a + b;

}

int main(void)

{

Integer n(100);

n = 200;

n.Display();

int sum = add(n, 100);

cout << sum << endl;

int x = n;

int y = static_cast<int>(n);

return 0;

}

其中n = 200; 是隱式將int 轉換成Interger類;int x = n; 是調用operator int 將Interger 類轉換成int,也可以使用static_cast 辦到;此外add 函數傳參時也會調用operator int 進行轉換。

二、->運算符重載

類* operator->();

類& operator*();

C++ Code

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

#include <iostream>

using namespace std;

class DBHelper

{

public:

DBHelper()

{

cout << "DB ..." << endl;

}

~DBHelper()

{

cout << "~DB ..." << endl;

}

void Open()

{

cout << "Open ..." << endl;

}

void Close()

{

cout << "Close ..." << endl;

}

void Query()

{

cout << "Query ..." << endl;

}

};

class DB

{

public:

DB()

{

db_ = new DBHelper;

}

~DB()

{

delete db_;

}

DBHelper *operator->()

{

return db_;

}

DBHelper &operator*()

{

return *db_;

}

private:

DBHelper *db_;

};

int main(void)

{

DB db;

db->Open();

db->Query();

db->Close();

(*db).Open();

(*db).Query();

(*db).Close();

return 0;

}

db->Open(); 等價於 (db.operator->())->Open(); 會調用operator-> 返回DBHelper類的指針,調用DBHelper的成員函數Open()。這樣使用的好處是不需要知道db 對象什麼時候需要釋放,當生存期結束時,會調用DB類的析構函數,裡面delete db_; 故也會調用DBHelper類的析構函數。

(*db).Open(); 等價於(db.operator*()).Open();

三、operator new 和 operator delete

在前面曾經提過:實際上new 有三種用法,包括operator new、new operator、placement new,new operator 包含operator new,而placement new 則沒有內存分配而是直接調用構造函數。下面看例子:

C++ Code

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

#include <iostream>

using namespace std;

class Test

{

public:

Test(int n) : n_(n)

{

cout << "Test(int n) : n_(n)" << endl;

}

Test(const Test &other)

{

cout << "Test(const Test& other)" << endl;

}

~Test()

{

cout << "~Test()" << endl;

}

/****************************************************************/

void *operator new(size_t size)

{

cout << "void* operator new(size_t size)" << endl;

void *p = malloc(size);

return p;

}

void operator delete(void *p) //與下面的operator delete函數類似,共存的話優先;

{

//匹配上面的operator new 函數

cout << "void operator delete(void* p)" << endl;

free(p);

}

void operator delete(void *p, size_t size)

{

cout << "void operator delete(void* p, size_t size)" << endl;

free(p);

}

/**********************************************************************/

void *operator new(size_t size, const char *file, long line)

{

cout << " void* operator new(size_t size, const char* file, long line);" << endl;

cout << file << ":" << line << endl;

void *p = malloc(size);

return p;

}

void operator delete(void *p, const char *file, long line)

{

cout << " void operator delete(void* p, const char* file, long line);" << endl;

cout << file << ":" << line << endl;

free(p);

}

void operator delete(void *p, size_t size, const char *file, long line)

{

cout << "void operator delete(void* p, size_t size, const char* file, long line);" << endl;

cout << file << ":" << line << endl;

free(p);

}

/**************************************************************************/

void *operator new(size_t size, void *p)

{

cout << "void* operator new(size_t size, void* p);" << endl;

return p;

}

void operator delete(void *, void *)

{

cout << "void operator delete(void *, void *);" << endl;

}

/**************************************************************************/

int n_;

};

/*************** global **********************************************/

void *operator new(size_t size)

{

cout << "global void* operator new(size_t size)" << endl;

void *p = malloc(size);

return p;

}

void operator delete(void *p)

{

cout << "global void operator delete(void* p)" << endl;

free(p);

}

/**********************************************************************/

void *operator new[](size_t size)

{

cout << "global void* operator new[](size_t size)" << endl;

void *p = malloc(size);

return p;

}

void operator delete[](void *p)

{

cout << "global void operator delete[](void* p)" << endl;

free(p);

}

/***********************************************************************/

int main(void)

{

Test *p1 = new Test(100); // new operator = operator new + 構造函數的調用

delete p1;

char *str1 = new char;

delete str1;

char *str2 = new char[100];

delete[] str2;

char chunk[10];

Test *p2 = new (chunk) Test(200); //operator new(size_t, void *_Where)

// placement new,不分配內存 + 構造函數的調用

cout << p2->n_ << endl;

p2->~Test(); // 顯式調用析構函數

//Test* p3 = (Test*)chunk;

Test *p3 = reinterpret_cast<Test *>(chunk);

cout << p3->n_ << endl;

#define new new(__FILE__, __LINE__)

//Test* p4 = new(__FILE__, __LINE__) Test(300);

Test *p4 = new Test(300);

delete p4;

return 0;

}

類型轉換運算符 運算符重載 operator new operator delete

從輸出可以看出幾點:

1、new operator 是分配內存(調用operator new) + 調用構造函數

2、operator new 是只分配內存,不調用構造函數

3、placement new 是不分配內存(調用operator new(與2是不同的函數) 返回已分配的內存地址),調用構造函數

4、delete 是先調用析構函數,再調用operator delete.

5、如果new 的是數組,對應地也需要delete [] 釋放

注意:

1、如果存在繼承或者對象成員,那麼調用構造函數或者析構函數時將有多個,按一定順序調用,參見這裡。

2、假設存在繼承,delete 基類指針;涉及到虛析構函數的問題,參見這裡。

最後還存在一點疑問的是 delete p4 為什麼調用的不是 void operator delete(void* p, const char* file, long line); 而是

void operator delete(void* p) ; 希望有明白的朋友告訴我一聲。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

Canvas API詳解(Part 1)
在Linux上增加swap空間的技巧

TAG:程序員小新人學習 |