圖形
矩形、正方形、圓形
計(jì)算面積、面積輸出
·面向?qū)ο笤O(shè)計(jì),類?
·實(shí)現(xiàn)功能?
·運(yùn)行時多態(tài)性測試?
1 #include <iostream>
2 using namespace std;
3
4 class Shape
5 {
6 protected:
7 double area;
8 public:
9 virtual double getArea() const = 0;
10 virtual void showArea()
11 {
12 cout << area << endl;
13 }
14 // friend ostream& operator << (ostream& out, const Shape& s);
15 };
16
17 ostream& operator << (ostream& out, const Shape& s)
18 {
19 out << s.getArea();
20 return out;
21 }
22
23 class Rectangle : public Shape
24 {
25 private:
26 double x;
27 double y;
28 public:
29 Rectangle(double i = 0.0, double j = 0.0) : x(i), y(j)
30 {
31 area = x * y;
32 }
33 virtual double getArea() const
34 {
35 return area;
36 }
37 };
38
39 class Square : public Shape
40 {
41 private:
42 double x;
43 public:
44 Square(double i = 0.0) : x(i)
45 {
46 area = x * x;
47 }
48 virtual double getArea() const
49 {
50 return area;
51 }
52 };
53
54 class Circle : public Shape
55 {
56 private:
57 double r;
58 static const double PI;
59 public:
60 Circle(double i = 0.0) : r(i)
61 {
62 area = PI * r * r;
63 }
64 virtual double getArea() const
65 {
66 return area;
67 }
68 };
69
70 const double Circle::PI = 3.1415926;
71
72 int main()
73 {
74 Shape* p;
75 p = new Rectangle(4, 5);
76 cout << p->getArea() << endl;
77 p->showArea();
78 delete p;
79 p = new Square(5);
80 cout << p->getArea() << endl;
81 p->showArea();
82 delete p;
83 p = new Circle(5);
84 cout << p->getArea() << endl;
85 p->showArea();
86 delete p;
87
88
89 Rectangle r(6, 7);
90 Square s(7);
91 Circle c(9);
92 cout << r << endl;
93 cout << s << endl;
94 cout << c << endl;
95
96 return 0;
97 }
posted @
2011-06-16 11:46 unixfy 閱讀(200) |
評論 (0) |
編輯 收藏
賦值運(yùn)算符的重載,有不同的方法,Effective C++ 中有一個條款對此介紹。
1 #include <iostream>
2 using namespace std;
3
4 class MyString
5 {
6 private:
7 unsigned len;
8 char* data;
9 public:
10 MyString(const char* s = "");
11 MyString(const MyString& s);
12 MyString& operator = (const MyString& s);
13 ~MyString();
14 };
15
16 MyString::MyString(const char* s)
17 {
18 len = strlen(s);
19 data = new char[len + 1];
20 if (data != 0)
21 {
22 strcpy(data, s);
23 }
24 }
25
26 MyString::MyString(const MyString& s)
27 {
28 len = s.len;
29 data = new char[len + 1];
30 if (data != 0)
31 {
32 strcpy(data, s.data);
33 }
34 }
35
36 MyString& MyString:: operator = (const MyString& s)
37 {
38 // 第一種方法,需要檢測自賦值,因?yàn)槿绻粰z測,則會造成當(dāng)自賦值時,就直接將該對象的 data delete 了,也就是 s.data 被 delete 了。這時 s.data 是個懸置指針,所致內(nèi)存極可能無效
39 //
40 //if (this != &s)
41 //{
42 // delete [] data;
43 // len = s.len;
44 // data = new char[len + 1];
45 // if (data != 0)
46 // {
47 // strcpy(data, s.data);
48 // }
49 //}
50 //return *this;
51
52 // 另一種方法, 不需要檢測自賦值
53 // 這種方式需要做一個備份,自賦值情況下,temp 保持了另一份備份,即便 delete 了 data 還是留有一份
54 // 非自賦值的情況下,對 s.data 所指的內(nèi)容有了一個備份,然后 delete data,將 temp 賦予 data,這樣有了兩份 s.data,到達(dá)賦值的目的
55 len = s.len;
56 char* temp = new char[len + 1];
57 if (temp != 0)
58 {
59 strcpy(temp, s.data);
60 }
61 delete [] data;
62 data = temp;
63 return *this;
64
65 // 兩種方法的代價分析
66 // 第一種方法,需要每次都要檢測是不是自賦值了,對于自賦值的情況,雖然檢測了,但是避免了備份,有利于自賦值的情況。但是對于非自賦值的情況,都需要額外的檢測,這種檢測是浪費(fèi)的
67 // 第二種方法,不管是自賦值還是非自賦值都需要備份,這種方法對于自賦值的情況,較第一種方法代價高些,但是對于非自賦值的情況它不需要檢測,也是做一個 copy 所以非自賦值的情況效率由于第一種方法
68 // 也就是說第一種方法對于自賦值的情況好,第二種方法對于非自賦值的情況好。一般情況下,自賦值的情況并不經(jīng)常出現(xiàn),所以第一種檢測自賦值的操作很多情況下是多余的,所以相對第一種方法,第二種方法更好些。
69 }
70
71 MyString::~MyString()
72 {
73 len = 0;
74 delete [] data;
75 }
76
77 int main()
78 {
79 MyString a("C++ Programming"), c("Hello");
80 MyString b(a);
81 c = b;
82 cout << ". . ." << endl;
83 return 0;
84 }
posted @
2011-06-16 10:56 unixfy 閱讀(243) |
評論 (0) |
編輯 收藏
Function 語意學(xué)
static member functions 不可能做的
·存取 nonstatic 數(shù)據(jù)
·被聲明為 const
·virtual
·volatile
this
·T* const this
·const T* const this
名字的特殊處理 name mangling
名字_類名_參數(shù)鏈表
((Point3d*)0)->object_count();
virtual member functions
虛擬成員函數(shù)
任何問題都可以通過添加一個中間層來解決,實(shí)現(xiàn)多態(tài)就是通過添加了一個虛函數(shù)表和虛函數(shù)表指針這個中間層實(shí)現(xiàn)的
多重繼承下的 virtual functions
thunk
address points
virtual base class
不要聲明 nonstatic data member
構(gòu)造函數(shù)的調(diào)用
指向 member function 的指針
double (Point::*pmf)();
指向 virtual member functions 的指針
ptr->z()
(ptr->*pmf)();
指向成員的指針實(shí)質(zhì)是索引,而不是地址
在我看來不管是 virtual member functions 的指針還是 nonvirtual member functions 的指針
posted @
2011-06-01 13:45 unixfy 閱讀(189) |
評論 (0) |
編輯 收藏
第三章 Data 語意學(xué)
class object 的大小
·支持語言特性(virtual)自動添加的 data members
·alignment 的需要
empty virtual base class
Data Member 的綁定
·成員完全可見,可以在后面
·類型定義應(yīng)該放在最前面
Data Member 的布局
static const 成員初始化
const 成員初始化
Data Member 的存取
static data members
static data member 編碼
name-mangling
nonstatic data members
origin._y = 0.0;
&origin + (&Point3d::_y - 1);
多態(tài),指針或引用
但是如果是 (*p).foo() ?
繼承與 Data Member
多態(tài)
虛擬繼承
·virtual base class table
·virtual function table - offset
對象成員的效率
指向 Data Member 的指針
posted @
2011-05-28 13:22 unixfy 閱讀(87) |
評論 (0) |
編輯 收藏
怎樣把函數(shù)模板聲明為類模板的友元
給類模板聲明友元的函數(shù)模板有三種方式,分別為:
第一種方式,在模板類內(nèi)部聲明友元的函數(shù)模板
第二種方式,在模板類內(nèi)部聲明對應(yīng)版本的友元函數(shù)模板實(shí)例化
需要前置聲明
這種方式是最為合理的方式
第三種方式,在模板類內(nèi)部直接聲明友元函數(shù),不涉及函數(shù)模板
這種情況只能在模板類內(nèi)部一起把函數(shù)的定義寫出來,不能在外部實(shí)現(xiàn),因?yàn)橥獠啃枰愋蛥?shù),而需要類型參數(shù)就是模板了
其實(shí)這種情況相當(dāng)于一般的模板類的成員函數(shù),也就是相當(dāng)于一個函數(shù)模板
第二種方式也是一個函數(shù)模板,他們保持函數(shù)的參數(shù)類型和該模板類的實(shí)例一個類型
第一種方式更為靈活,他不會要求參數(shù)類型與模板類實(shí)例是一個類型,但是一般情況下我們也是按照一個類型使用的。
1 #include <iostream>
2 using namespace std;
3
4 //// 第一種方式,在模板類內(nèi)部聲明友元的函數(shù)模板
5 //template <typename T>
6 //class C
7 //{
8 //private:
9 // T m[5];
10 //public:
11 // template <typename U>
12 // friend void foo(const C<U>& T);
13 //};
14 //
15 //template <typename T>
16 //void foo(const C<T>& t)
17 //{
18 // for (int i = 0; i < 5; ++i)
19 // {
20 // cout << t.m[i] << endl;
21 // }
22 //}
23
24 // 第二種方式,在模板類內(nèi)部聲明對應(yīng)版本的友元函數(shù)模板實(shí)例化
25 // 需要前置聲明
26 // 這種方式是最為合理的方式
27 template <typename T>
28 class C;
29
30 template <typename T>
31 void foo(const C<T>& t);
32
33 template <typename T>
34 class C
35 {
36 private:
37 T m[5];
38 public:
39 friend void foo<T>(const C<T>& t);
40 };
41
42 template <typename T>
43 void foo(const C<T>& t)
44 {
45 for (int i = 0; i < 5; ++i)
46 {
47 cout << t.m[i] << endl;
48 }
49 }
50
51 //// 第三種方式,在模板類內(nèi)部直接聲明友元函數(shù),不涉及函數(shù)模板
52 //// 這種情況只能在模板類內(nèi)部一起把函數(shù)的定義寫出來,不能在外部實(shí)現(xiàn),因?yàn)橥獠啃枰愋蛥?shù),而需要類型參數(shù)就是模板了
53 //// 其實(shí)這種情況相當(dāng)于一般的模板類的成員函數(shù),也就是相當(dāng)于一個函數(shù)模板
54 //// 第二種方式也是一個函數(shù)模板,他們保持函數(shù)的參數(shù)類型和該模板類的實(shí)例一個類型
55 //// 第一種方式更為靈活,他不會要求參數(shù)類型與模板類實(shí)例是一個類型,但是一般情況下我們也是按照一個類型使用的。
56 //template <typename T>
57 //class C
58 //{
59 //private:
60 // T m[5];
61 //public:
62 // friend void foo(const C<T>& t)
63 // {
64 // for (int i = 0; i < 5; ++i)
65 // {
66 // cout << (t.m[i]) << endl;
67 // }
68 // }
69 //};
70
71 int main()
72 {
73 // C<int> c;
74 C<double> c;
75 foo(c);
76 return 0;
77 }
http://topic.csdn.net/u/20100619/21/c32066bb-dacd-4938-8f95-7345a522b0f6.html
http://topic.csdn.net/u/20100612/13/9365495d-b1d8-4e87-b704-23895acb1637.html
http://www.cnblogs.com/wswqwps/archive/2008/10/25/1319320.html
http://blog.csdn.net/dongzhongshu/archive/2011/02/22/6200466.aspx
posted @
2011-05-27 23:59 unixfy 閱讀(1881) |
評論 (0) |
編輯 收藏
swap 到底做了什么
swap 交換兩個內(nèi)置數(shù)據(jù)類型的變量時,直接交換。
swap 交換自定義類型對象時,如果里面沒有成員指針,直接交換各個對應(yīng)成員。
如果自定義類型中有指針成員,則是交換兩個指針的值,但是指針的指向的值得不到交換。
正是由于這個原因,可以用 swap 進(jìn)行重載 operator = 時避免自賦值情況,而是生產(chǎn)一個臨時對象,然后與本對象 swap 即可。
關(guān)于重載 operator = 自賦值的情況,更詳細(xì)內(nèi)容可以查看《Effective C++》
實(shí)驗(yàn)程序:
1 #include <iostream>
2 using namespace std;
3
4 class Str
5 {
6 private:
7 char* s_;
8 public:
9 Str(const char* s = "")
10 {
11 s_ = new char[strlen(s) + 1];
12 if (s_ == 0)
13 {
14 cout << "test" << endl;
15 exit(1);
16 }
17 strcpy(s_, s);
18 }
19 // 定義拷貝構(gòu)造函數(shù),這里會被用于 operator =,swap
20 Str(const Str& rhs)
21 {
22 s_ = new char[strlen(rhs.s_) + 1];
23 if (s_ == 0)
24 {
25 cout << "test" << endl;
26 exit(1);
27 }
28 strcpy(s_, rhs.s_);
29 }
30 ~Str()
31 {
32 clear();
33 }
34 //// 常規(guī)的 operator = 重載實(shí)現(xiàn)方式,必須檢查自賦值
35 //// 因?yàn)槿绻蛔再x值檢驗(yàn),對于自賦值現(xiàn)象如果不調(diào)用 clear,則 s_ 在 new 之后就改變,rhs 也改變,原來的丟失,后來的也不是合法內(nèi)容
36 //// 如果調(diào)用 clear,不會內(nèi)存泄露,但是 rhs 的內(nèi)容被釋放掉,rhs 的內(nèi)容也不是合法內(nèi)容。
37 //// 如果檢驗(yàn)自賦值,而沒有 clear,原來 *this 的那塊內(nèi)存會被丟失,造成內(nèi)存泄露。
38 //Str& operator = (const Str& rhs)
39 //{
40 // if (this != &rhs)
41 // {
42 // clear();
43 // s_ = new char[strlen(rhs.s_) + 1];
44 // if (s_ == 0)
45 // {
46 // exit(1);
47 // }
48 // strcpy(s_, rhs.s_);
49 // }
50 // return *this;
51 //}
52
53 // 改進(jìn)的 operator,先用一個 temp 保持 rhs,然后 swap
54 // 這種方式不怕自賦值,因?yàn)槿绻亲再x值,也有一個備份 temp,操作值相同的兩個對象 *this 和 temp,直接交換不會影響結(jié)果
55 // 如果不是自賦值,不是交換 *this 和 rhs,而是交換 *this 和 rhs 的一個復(fù)制品 temp,最終 *this 得到的值就是 rhs 的一個副本,完成賦值
56 // 這種方式不用檢驗(yàn)自賦值,所以可以省去每次調(diào)用時的自賦值檢驗(yàn),在基本上不會遇到自賦值檢驗(yàn)的情況下,這種方法可以省去很多誤用的檢驗(yàn)
57 // 但是它會每次生成一個副本,這樣做的效率與原來的非自賦值一樣,而且還需要一個 swap,但是這種方式是異常安全的,用對象來管理資源,資源分配即初始化
58 Str& operator = (const Str& rhs)
59 {
60 cout << "test" << endl;
61 Str temp(rhs);
62 // swap(*this, temp);
63 // 這里會引起遞歸調(diào)用,因?yàn)?nbsp;operator = 調(diào)用 swap,swap 內(nèi)部又調(diào)用 operator = ,一直遞歸下去,直到棧溢出
64 swap(s_, temp.s_);
65 // Effective C++ 中提到,可以定義一個成員函數(shù) swap,用于交換兩個對象對應(yīng)的數(shù)據(jù)成員。這樣可以防止無限遞歸。
66 // 另一種好的方式是除定義一個成員函數(shù) swap 外,傳參類型為 值類型 T,這樣就可以直接交換返回。
67 // 這些方法的前提都是要有定義拷貝構(gòu)造函數(shù)的。
68 return *this;
69 }
70
71 void clear()
72 {
73 delete [] s_;
74 }
75 void foo()
76 {
77 cout << s_ << endl;
78 }
79 };
80
81 int main()
82 {
83 int a = 3, b = 5;
84 swap(a, b);
85 cout << a << endl;
86 cout << b << endl;
87
88 Str s1("abc");
89 Str s2("xyz");
90 s1.foo();
91 s2.foo();
92
93 swap(s1, s2);
94 // 這里輸出兩個 test,我們得知,有兩個賦值操作
95 // 可以推測 swap 的內(nèi)部實(shí)現(xiàn)是 T t(s2), s2 = s1, s1 = t;
96 s1.foo();
97 s2.foo();
98
99 s2 = s1;
100 s1.foo();
101 s2.foo();
102
103 return 0;
104 }
posted @
2011-05-27 22:14 unixfy 閱讀(891) |
評論 (0) |
編輯 收藏
棧和堆是內(nèi)存中的部分。安裝地址的變化規(guī)則,棧是向下生長的,堆是向上增長的。
這里對棧和堆的地址生長情況做了一個實(shí)現(xiàn)。
更好的內(nèi)容有 Computer System:A Programmer's Perspective 《深入理解計(jì)算機(jī)系統(tǒng)》
1 #include <iostream>
2 using namespace std;
3
4 int main()
5 {
6 int i = 1;
7 int j = 2;
8 int k = 3;
9 cout << &i << endl;
10 cout << &j << endl;
11 cout << &k << endl;
12 // 棧是向下生長的,所以地址遞減
13
14 int a[3];
15 cout << &a[0] << endl;
16 cout << &a[1] << endl;
17 cout << &a[2] << endl;
18 // 棧還是向下生長的,但是對于一個數(shù)組來說從第一個元素到后面的元素
19 // 其每個元素的地址是遞增的。所以最后一個元素是在最上面的,也就是
20 // 與前面在棧上定義的元素挨著,第一個元素在最下面
21
22
23 cout << a[3] << endl;
24 cout << a[5] << endl;
25 // 這里 a[5] 輸出 3,a + 5 將達(dá)到變量 k 的地址 &k,所以 *(a + 5) = k
26
27
28 int* b = new int[3];
29 cout << &b[0] << endl;
30 cout << &b[1] << endl;
31 cout << &b[2] << endl;
32 // 堆是向上生長的,第一個元素在最下面
33
34 // 不管是在堆還是在棧上的數(shù)組,數(shù)組中的元素的地址都是隨著元素的位
35 // 置遞增而遞增的。
36 // 只不過在棧上的元素順序與棧的增長方向相反,在堆上數(shù)組的元素的順
37 // 序與堆的增長方向相同。
38
39 return 0;
40 }
posted @
2011-05-27 01:00 unixfy 閱讀(401) |
評論 (0) |
編輯 收藏
關(guān)于訪問權(quán)限和繼承方式
訪問權(quán)限有三種:public、protected、private
繼承也有三種:public、protected、private,這里不考慮 virtual 繼承。
繼承時的權(quán)限,不是針對本類內(nèi)的訪問權(quán)限,而是針對該派生類的客戶端代碼(包括其派生類)的訪問權(quán)限。
即是,對于基類中的 public、protected 成員,如果一個派生類 private 繼承自該基類,則這些成員還是可以在派生類中訪問的,只是不能在該派生類的客戶代碼中被直接訪問,或者在該派生類的派生類中直接訪問。
也就是說,繼承的方式是針對派生類的客戶端代碼來講的,對派生類內(nèi)部不起作用,不管是 public、protected、private 繼承,派生類中總是可以訪問基類中的 public、protected 成員,基類中的 private 成員永遠(yuǎn)不能在派生類中直接訪問,不論通過哪種方式。
歸納一下:
成員訪問權(quán)限 繼承方式 派生類中能否訪問 派生類的派生類中 派生類的客戶端代碼
public public 能 能 能
public protected 能 能 不能
public private 能 不能 不能
protected public 能 能 不能
protected protected 能 能 不能
protected private 能 不能 不能
private public 不能 不能 不能
private protected 不能 不能 不能
private private 不能 不能 不能
從這個表中,我們更能清除地看到成員訪問權(quán)限和繼承方式之間的組合,對派生類中的訪問、派生類的派生類中的訪問、派生類的客戶端代碼的訪問控制情況。
繼承的方式是在原有基類訪問權(quán)限的基礎(chǔ)上,給在派生類的訪問權(quán)限又加了一個效應(yīng)。取兩個中最嚴(yán)格的那個權(quán)限,這個取得的權(quán)限是派生類成員的訪問權(quán)限,而這種訪問權(quán)限對派生類的客戶端代碼和派生類的派生類代碼其訪問控制作用。
posted @
2011-05-27 00:20 unixfy 閱讀(453) |
評論 (0) |
編輯 收藏
隊(duì)列的兩個主要操作:入隊(duì)列、出隊(duì)列
棧的兩個主要操作:入棧、出棧
入隊(duì)列對應(yīng)入棧
出隊(duì)列是出最早的,出棧是出最晚的
使用 360 瀏覽器,有個不錯的功能是可以恢復(fù)標(biāo)簽,你關(guān)閉一個標(biāo)簽,這個標(biāo)簽就會進(jìn)入待恢復(fù)表,如果待恢復(fù)表慢了,新加標(biāo)簽,最早的標(biāo)簽會消失,這是 FIFO 隊(duì)列。
但是如果點(diǎn)擊恢復(fù)標(biāo)簽隊(duì)列,會恢復(fù)最近關(guān)閉的標(biāo)簽,也就是最晚進(jìn)入待恢復(fù)表中的標(biāo)簽,所以這又是一種 LIFO 棧。
待恢復(fù)表既具有添加標(biāo)簽的 FIFO 隊(duì)列性質(zhì),又具有恢復(fù)標(biāo)簽并移除標(biāo)簽的 LIFO 棧性質(zhì)。
實(shí)現(xiàn)一個數(shù)據(jù)結(jié)構(gòu),使其既具有 FIFO 隊(duì)列的性質(zhì),又具有 LIFO 棧的性質(zhì)。
由于標(biāo)簽有很多,這里使用循環(huán)表來實(shí)現(xiàn)這個數(shù)據(jù)結(jié)構(gòu),早期的標(biāo)簽會隨著新加入的標(biāo)簽被覆蓋。
注意連續(xù)關(guān)閉兩個相同的標(biāo)簽,第二次關(guān)閉時,不會將這個標(biāo)簽存入待恢復(fù)表中。
這個表主要有三個操作
·入隊(duì)列
·出隊(duì)列
·出棧
沒有入棧,其實(shí)入棧也就是入隊(duì)列。
實(shí)現(xiàn):
1 #include <iostream>
2 using namespace std;
3
4 class Table360
5 {
6 private:
7 int capacity_;
8 int* data_;
9 int size_;
10 int head_;
11 int tail_;
12 public:
13 Table360(int c = 10) : capacity_(c)
14 {
15 data_ = new int[capacity_];
16 if (data_ == 0)
17 {
18 exit(1);
19 }
20 memset(data_, 0, sizeof (int) * capacity_);
21 size_ = 0;
22 head_ = 0;
23 tail_ = -1;
24 }
25 Table360(const Table360& t) : capacity_(t.capacity_)
26 {
27 data_ = new int[capacity_];
28 if (data_ == 0)
29 {
30 exit(1);
31 }
32 memset(data_, 0, sizeof (int) * capacity_);
33 size_ = t.size_;
34 head_ = t.head_;
35 tail_ = t.tail_;
36 for (int i = 0; i < size_; ++i)
37 {
38 data_[(head_+i) % capacity_] = t.data_[(t.head_ + i) % t.capacity_];
39 }
40 }
41 void swap_(Table360& t)
42 {
43 swap(capacity_, t.capacity_);
44 swap(data_, t.data_);
45 swap(size_, t.size_);
46 swap(head_, t.head_);
47 swap(tail_, t.tail_);
48 }
49 Table360& operator = (const Table360& t)
50 {
51 Table360 temp(t);
52 swap_(temp);
53 return *this;
54 }
55 ~Table360()
56 {
57 delete [] data_;
58 capacity_ = 0;
59 size_ = 0;
60 head_ = 0;
61 tail_ = 0;
62 }
63 int size()
64 {
65 return size_;
66 }
67 bool empty()
68 {
69 return size_ == 0;
70 }
71 int top()
72 {
73 return data_[head_];
74 }
75 void enQueue(int item)
76 {
77 if (size_ >= capacity_)
78 {
79 deQueue();
80 }
81 tail_ = (tail_ + 1) % capacity_;
82 data_[tail_] = item;
83 ++size_;
84 //if (size_ >= capacity_)
85 //{
86 // head_ = (head_ + 1) % capacity_;
87 // --size_;
88 // tail_ = (tail_ + 1) % capacity_;
89 // data_[tail_] = item;
90 // ++size_;
91 //}
92 //else
93 //{
94 // tail_ = (tail_ + 1) % capacity_;
95 // data_[tail_] = item;
96 // ++size_;
97 //}
98 }
99 void deQueue()
100 {
101 head_ = ++head_ % capacity_;
102 --size_;
103 }
104 // 其實(shí)沒有入棧操作,入棧即是入隊(duì)列
105 void push(int item)
106 {
107 enQueue(item);
108 }
109 int pop()
110 {
111 int tmp = tail_;
112 tail_ = (tail_ + capacity_ - 1) % capacity_;
113 --size_;
114 return data_[tmp];
115 }
116 int stacktop()
117 {
118 return data_[tail_];
119 }
120 };
121
122 int main()
123 {
124 Table360 t(20);
125 cout << t.size() << endl;
126 for (int i = 0; i < 100; ++i)
127 {
128 t.enQueue(i);
129 }
130 cout << t.size() << endl;
131 // cout << t.top() << endl;
132 while (!t.empty())
133 {
134 // cout << t.pop() << ' ';
135 cout << t.stacktop() << ' ';
136 t.pop();
137 }
138 cout << endl;
139 return 0;
140 }
其他鏈接:
http://zh.wikipedia.org/wiki/%E9%98%9F%E5%88%97
http://zh.wikipedia.org/wiki/%E5%A0%86%E6%A0%88
http://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84
http://student.zjzk.cn/course_ware/data_structure/web/zhanhuoduilie/zhanhuoduilie3.2.1.htm
http://student.zjzk.cn/course_ware/data_structure/web/zhanhuoduilie/zhanhuoduilie3.1.1.htm
http://student.zjzk.cn/course_ware/data_structure/web/main.htm
posted @
2011-05-26 00:48 unixfy 閱讀(138) |
評論 (0) |
編輯 收藏
《深度探索 C++ 對象模型》讀書筆記——第一章 關(guān)于對象
C++ 對象模型
·語言中直接支持面向?qū)ο蟪绦蛟O(shè)計(jì)的部分
·對于各種支持的底層實(shí)現(xiàn)機(jī)制
virtual table
理解底層實(shí)現(xiàn)模型的好處有
·寫出效率較高的代碼
·有更好的自信心
關(guān)于對象
布局、存取時間來自于
·virtual: virtual function, virtual base class
·derived class 與 base class 的轉(zhuǎn)換
class data members: static, nonstatic
class member functions: static, nonstatic, virtual
1.簡單對象模型 Simple Object Model
slots
指向成員的指針
2.表格驅(qū)動對象模型
data member table
member function table: slots
Member Table 對象模型
支持 virtual functions
3.C++ 對象模型
virtual table (vtbl)
vptr: constructor, destructor, copy assignment
type_info object for RTTI(運(yùn)行時類型識別)
優(yōu)點(diǎn):空間和存取時間的效率
缺點(diǎn):會導(dǎo)致重新編譯
bptr
(*px->vtbl[2])(px);
(*px->vtbl[1])(px);
_delete(px);
vptr
virtual table
-----
address -> type_info for X
address -> X::~X()
address -> X::foo()
-----
pt->vtbl[0]
pt->vtbl[1]
pt->vtbl[2]
關(guān)鍵字所帶來的差異
組合而非繼承是把 C 和 C++ 結(jié)合在一起的唯一可行方法
conversion 運(yùn)算符
operator C_point()
{
return _c_point;
}
對象的差異
C++ 程序設(shè)計(jì)模型直接支持三種程序設(shè)計(jì)典范 programming paradigms
·程序模型 procedural model
·抽象數(shù)據(jù)類型模型 abstract data type model
·面向?qū)ο竽P?object-oriented model
C++ 支持多態(tài)的方法
·隱含轉(zhuǎn)化 Shape* ps = new circle();
·virtual function ps->rotate();
·dynamic_cast, typeid
if (Circle* pc = dynamic_cast<Circle*>(ps))
{
...
}
class object 內(nèi)存
·nonstatic data members
·alignment
·virutal(virtual functions, virtual base class)
dynamic_cast<Base*>
OB: object-based
OO: object-oriented
posted @
2011-05-25 18:48 unixfy 閱讀(142) |
評論 (0) |
編輯 收藏