青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 183,  comments - 10,  trackbacks - 0
 

圖形
矩形、正方形、圓形
計算面積、面積輸出

·面向對象設計,類?
·實現功能?
·運行時多態性測試?

 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& outconst 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.0double 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(45);
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(67);
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 閱讀(209) | 評論 (0)編輯 收藏
賦值運算符的重載,有不同的方法,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     // 第一種方法,需要檢測自賦值,因為如果不檢測,則會造成當自賦值時,就直接將該對象的 data delete 了,也就是 s.data 被 delete 了。這時 s.data 是個懸置指針,所致內存極可能無效
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 所指的內容有了一個備份,然后 delete data,將 temp 賦予 data,這樣有了兩份 s.data,到達賦值的目的
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     // 第一種方法,需要每次都要檢測是不是自賦值了,對于自賦值的情況,雖然檢測了,但是避免了備份,有利于自賦值的情況。但是對于非自賦值的情況,都需要額外的檢測,這種檢測是浪費的
67     // 第二種方法,不管是自賦值還是非自賦值都需要備份,這種方法對于自賦值的情況,較第一種方法代價高些,但是對于非自賦值的情況它不需要檢測,也是做一個 copy 所以非自賦值的情況效率由于第一種方法
68     // 也就是說第一種方法對于自賦值的情況好,第二種方法對于非自賦值的情況好。一般情況下,自賦值的情況并不經常出現,所以第一種檢測自賦值的操作很多情況下是多余的,所以相對第一種方法,第二種方法更好些。
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 閱讀(249) | 評論 (0)編輯 收藏

Function 語意學

static member functions 不可能做的
·存取 nonstatic 數據
·被聲明為 const
·virtual
·volatile

this
·T* const this
·const T* const this

名字的特殊處理 name mangling
名字_類名_參數鏈表

((Point3d*)0)->object_count();

virtual member functions
虛擬成員函數
任何問題都可以通過添加一個中間層來解決,實現多態就是通過添加了一個虛函數表和虛函數表指針這個中間層實現的

多重繼承下的 virtual functions

thunk
address points

virtual base class
不要聲明 nonstatic data member

構造函數的調用

指向 member function 的指針
double (Point::*pmf)();

指向 virtual member functions 的指針
ptr->z()
(ptr->*pmf)();
指向成員的指針實質是索引,而不是地址
在我看來不管是 virtual member functions 的指針還是 nonvirtual member functions 的指針

posted @ 2011-06-01 13:45 unixfy 閱讀(194) | 評論 (0)編輯 收藏

第三章 Data 語意學

class object 的大小
·支持語言特性(virtual)自動添加的 data members
·alignment 的需要

empty virtual base class

Data Member 的綁定
·成員完全可見,可以在后面
·類型定義應該放在最前面

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);

多態,指針或引用
但是如果是 (*p).foo() ?

繼承與 Data Member
多態
虛擬繼承

·virtual base class table
·virtual function table - offset

對象成員的效率

指向 Data Member 的指針

posted @ 2011-05-28 13:22 unixfy 閱讀(91) | 評論 (0)編輯 收藏

怎樣把函數模板聲明為類模板的友元

給類模板聲明友元的函數模板有三種方式,分別為:
第一種方式,在模板類內部聲明友元的函數模板
第二種方式,在模板類內部聲明對應版本的友元函數模板實例化
 需要前置聲明
 這種方式是最為合理的方式
第三種方式,在模板類內部直接聲明友元函數,不涉及函數模板
 這種情況只能在模板類內部一起把函數的定義寫出來,不能在外部實現,因為外部需要類型參數,而需要類型參數就是模板了
 其實這種情況相當于一般的模板類的成員函數,也就是相當于一個函數模板
 第二種方式也是一個函數模板,他們保持函數的參數類型和該模板類的實例一個類型
 第一種方式更為靈活,他不會要求參數類型與模板類實例是一個類型,但是一般情況下我們也是按照一個類型使用的。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 //// 第一種方式,在模板類內部聲明友元的函數模板
 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 // 第二種方式,在模板類內部聲明對應版本的友元函數模板實例化
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 //// 第三種方式,在模板類內部直接聲明友元函數,不涉及函數模板
52 //// 這種情況只能在模板類內部一起把函數的定義寫出來,不能在外部實現,因為外部需要類型參數,而需要類型參數就是模板了
53 //// 其實這種情況相當于一般的模板類的成員函數,也就是相當于一個函數模板
54 //// 第二種方式也是一個函數模板,他們保持函數的參數類型和該模板類的實例一個類型
55 //// 第一種方式更為靈活,他不會要求參數類型與模板類實例是一個類型,但是一般情況下我們也是按照一個類型使用的。
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 閱讀(1892) | 評論 (0)編輯 收藏

swap 到底做了什么
swap 交換兩個內置數據類型的變量時,直接交換。
swap 交換自定義類型對象時,如果里面沒有成員指針,直接交換各個對應成員。
如果自定義類型中有指針成員,則是交換兩個指針的值,但是指針的指向的值得不到交換。
正是由于這個原因,可以用 swap 進行重載 operator = 時避免自賦值情況,而是生產一個臨時對象,然后與本對象 swap 即可。

關于重載 operator = 自賦值的情況,更詳細內容可以查看《Effective C++》
實驗程序:

  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     // 定義拷貝構造函數,這里會被用于 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     //// 常規的 operator = 重載實現方式,必須檢查自賦值
 35     //// 因為如果不自賦值檢驗,對于自賦值現象如果不調用 clear,則 s_ 在 new 之后就改變,rhs 也改變,原來的丟失,后來的也不是合法內容
 36     //// 如果調用 clear,不會內存泄露,但是 rhs 的內容被釋放掉,rhs 的內容也不是合法內容。
 37     //// 如果檢驗自賦值,而沒有 clear,原來 *this 的那塊內存會被丟失,造成內存泄露。
 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     // 改進的 operator,先用一個 temp 保持 rhs,然后 swap
 54     // 這種方式不怕自賦值,因為如果是自賦值,也有一個備份 temp,操作值相同的兩個對象 *this 和 temp,直接交換不會影響結果
 55     // 如果不是自賦值,不是交換 *this 和 rhs,而是交換 *this 和 rhs 的一個復制品 temp,最終 *this 得到的值就是 rhs 的一個副本,完成賦值
 56     // 這種方式不用檢驗自賦值,所以可以省去每次調用時的自賦值檢驗,在基本上不會遇到自賦值檢驗的情況下,這種方法可以省去很多誤用的檢驗
 57     // 但是它會每次生成一個副本,這樣做的效率與原來的非自賦值一樣,而且還需要一個 swap,但是這種方式是異常安全的,用對象來管理資源,資源分配即初始化
 58     Str& operator = (const Str& rhs)
 59     {
 60         cout << "test" << endl;
 61         Str temp(rhs);
 62         // swap(*this, temp);
 63         // 這里會引起遞歸調用,因為 operator = 調用 swap,swap 內部又調用 operator = ,一直遞歸下去,直到棧溢出
 64         swap(s_, temp.s_);
 65         // Effective C++ 中提到,可以定義一個成員函數 swap,用于交換兩個對象對應的數據成員。這樣可以防止無限遞歸。
 66         // 另一種好的方式是除定義一個成員函數 swap 外,傳參類型為 值類型 T,這樣就可以直接交換返回。
 67         // 這些方法的前提都是要有定義拷貝構造函數的。
 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 的內部實現是 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 閱讀(899) | 評論 (0)編輯 收藏
棧和堆是內存中的部分。安裝地址的變化規則,棧是向下生長的,堆是向上增長的。
這里對棧和堆的地址生長情況做了一個實現。
更好的內容有 Computer System:A Programmer's Perspective 《深入理解計算機系統》
 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 << &<< endl;
10     cout << &<< endl;
11     cout << &<< endl;
12     // 棧是向下生長的,所以地址遞減
13 
14     int a[3];
15     cout << &a[0<< endl;
16     cout << &a[1<< endl;
17     cout << &a[2<< endl;
18     // 棧還是向下生長的,但是對于一個數組來說從第一個元素到后面的元素
19     // 其每個元素的地址是遞增的。所以最后一個元素是在最上面的,也就是
20     // 與前面在棧上定義的元素挨著,第一個元素在最下面
21 
22     
23     cout << a[3<< endl;
24     cout << a[5<< endl;
25     // 這里 a[5] 輸出 3,a + 5 將達到變量 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     // 不管是在堆還是在棧上的數組,數組中的元素的地址都是隨著元素的位
35     // 置遞增而遞增的。
36     // 只不過在棧上的元素順序與棧的增長方向相反,在堆上數組的元素的順
37     // 序與堆的增長方向相同。
38 
39     return 0;
40 }

posted @ 2011-05-27 01:00 unixfy 閱讀(405) | 評論 (0)編輯 收藏

關于訪問權限和繼承方式
訪問權限有三種:public、protected、private
繼承也有三種:public、protected、private,這里不考慮 virtual 繼承。
繼承時的權限,不是針對本類內的訪問權限,而是針對該派生類的客戶端代碼(包括其派生類)的訪問權限。
即是,對于基類中的 public、protected 成員,如果一個派生類 private 繼承自該基類,則這些成員還是可以在派生類中訪問的,只是不能在該派生類的客戶代碼中被直接訪問,或者在該派生類的派生類中直接訪問。
也就是說,繼承的方式是針對派生類的客戶端代碼來講的,對派生類內部不起作用,不管是 public、protected、private 繼承,派生類中總是可以訪問基類中的 public、protected 成員,基類中的 private 成員永遠不能在派生類中直接訪問,不論通過哪種方式。
歸納一下:
成員訪問權限        繼承方式        派生類中能否訪問        派生類的派生類中        派生類的客戶端代碼
public              public          能                      能                      能
public              protected       能                      能                      不能
public              private         能                      不能                    不能
protected           public          能                      能                      不能
protected           protected       能                      能                      不能
protected           private         能                      不能                    不能
private             public          不能                    不能                    不能
private             protected       不能                    不能                    不能
private             private         不能                    不能                    不能

從這個表中,我們更能清除地看到成員訪問權限和繼承方式之間的組合,對派生類中的訪問、派生類的派生類中的訪問、派生類的客戶端代碼的訪問控制情況。


繼承的方式是在原有基類訪問權限的基礎上,給在派生類的訪問權限又加了一個效應。取兩個中最嚴格的那個權限,這個取得的權限是派生類成員的訪問權限,而這種訪問權限對派生類的客戶端代碼和派生類的派生類代碼其訪問控制作用。

posted @ 2011-05-27 00:20 unixfy 閱讀(462) | 評論 (0)編輯 收藏

隊列的兩個主要操作:入隊列、出隊列
棧的兩個主要操作:入棧、出棧
入隊列對應入棧
出隊列是出最早的,出棧是出最晚的

使用 360 瀏覽器,有個不錯的功能是可以恢復標簽,你關閉一個標簽,這個標簽就會進入待恢復表,如果待恢復表慢了,新加標簽,最早的標簽會消失,這是 FIFO 隊列。
但是如果點擊恢復標簽隊列,會恢復最近關閉的標簽,也就是最晚進入待恢復表中的標簽,所以這又是一種 LIFO 棧。

待恢復表既具有添加標簽的 FIFO 隊列性質,又具有恢復標簽并移除標簽的 LIFO 棧性質。
實現一個數據結構,使其既具有 FIFO 隊列的性質,又具有 LIFO 棧的性質。
由于標簽有很多,這里使用循環表來實現這個數據結構,早期的標簽會隨著新加入的標簽被覆蓋。

注意連續關閉兩個相同的標簽,第二次關閉時,不會將這個標簽存入待恢復表中。

這個表主要有三個操作
·入隊列
·出隊列
·出棧
沒有入棧,其實入棧也就是入隊列。

實現:

  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_, 0sizeof (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_, 0sizeof (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     // 其實沒有入棧操作,入棧即是入隊列
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 閱讀(146) | 評論 (0)編輯 收藏

《深度探索 C++ 對象模型》讀書筆記——第一章 關于對象

C++ 對象模型
·語言中直接支持面向對象程序設計的部分
·對于各種支持的底層實現機制

virtual table

理解底層實現模型的好處有
·寫出效率較高的代碼
·有更好的自信心


關于對象
布局、存取時間來自于
·virtual: virtual function, virtual base class
·derived class 與 base class 的轉換

class data members: static, nonstatic
class member functions: static, nonstatic, virtual

1.簡單對象模型 Simple Object Model
slots
指向成員的指針

2.表格驅動對象模型
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(運行時類型識別)

優點:空間和存取時間的效率
缺點:會導致重新編譯

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]

關鍵字所帶來的差異
組合而非繼承是把 C 和 C++ 結合在一起的唯一可行方法
conversion 運算符
operator C_point()
{
 return _c_point;
}

對象的差異
C++ 程序設計模型直接支持三種程序設計典范 programming paradigms
·程序模型 procedural model
·抽象數據類型模型 abstract data type model
·面向對象模型 object-oriented model

C++ 支持多態的方法
·隱含轉化 Shape* ps = new circle();
·virtual function ps->rotate();
·dynamic_cast, typeid
 if (Circle* pc = dynamic_cast<Circle*>(ps))
 {
 ...
 }

class object 內存
·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 閱讀(146) | 評論 (0)編輯 收藏
僅列出標題
共19頁: First 7 8 9 10 11 12 13 14 15 Last 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            鲁鲁狠狠狠7777一区二区| 国产精品中文字幕欧美| 亚洲深夜福利网站| 欧美激情视频给我| 亚洲精选视频免费看| 亚洲亚洲精品在线观看 | 国内精品久久久久影院色| 欧美在线播放| 久久综合久色欧美综合狠狠 | 99re6热在线精品视频播放速度| 欧美伦理影院| 欧美影视一区| 亚洲激情成人在线| 亚洲一品av免费观看| 国产午夜精品麻豆| 欧美成年人网| 欧美伊人久久| av成人免费观看| 久久综合色播五月| 一区二区三区高清在线观看| 国产无一区二区| 欧美成人a∨高清免费观看| 一区二区高清在线| 久久人人爽人人| 亚洲免费中文字幕| 在线看片成人| 国产日韩精品一区二区| 欧美国产日韩一区二区三区| 中文一区字幕| 亚洲国产欧美精品| 久久精品日产第一区二区三区| 亚洲美女中文字幕| 国内成+人亚洲| 国产精品日韩在线播放| 欧美国产1区2区| 久久久噜噜噜久久| 亚洲欧美影院| 一本一本a久久| 亚洲七七久久综合桃花剧情介绍| 久久久久久久久久久一区 | 久久精品一区二区三区不卡牛牛 | 久久综合一区二区| 亚洲欧美电影院| 亚洲精品综合| 91久久国产自产拍夜夜嗨| 黄色精品一区二区| 国产精品久久久久久福利一牛影视 | 亚洲视频在线一区观看| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美日韩一卡| 久久漫画官网| 久久久91精品国产| 欧美一级艳片视频免费观看| 亚洲神马久久| 99国内精品久久| 亚洲精品免费电影| 亚洲茄子视频| 99av国产精品欲麻豆| 欧美激情一区二区三区在线视频观看 | 亚洲毛片在线观看| 亚洲精品午夜| 亚洲在线观看免费| 亚洲欧美日韩精品在线| 香蕉亚洲视频| 久久精品99国产精品| 欧美在线观看日本一区| 性做久久久久久免费观看欧美| 午夜精品久久久久久久久| 午夜精品视频网站| 久久99伊人| 欧美电影免费| 99re热这里只有精品视频| 一区二区电影免费观看| 亚洲一区国产| 久久精品最新地址| 欧美v日韩v国产v| 黄色成人91| 免费影视亚洲| 欧美电影电视剧在线观看| 欧美大片国产精品| 欧美视频久久| 国产一区二区精品丝袜| 国产一区美女| 亚洲精品久久7777| 亚洲图片欧美日产| 欧美一级黄色录像| 久久伊人一区二区| 亚洲欧洲美洲综合色网| 亚洲伦理网站| 午夜精品久久久久久久久久久久久| 欧美诱惑福利视频| 免费欧美日韩| 国产精品一国产精品k频道56| 激情欧美一区| 一区二区三区精品视频在线观看| 午夜亚洲一区| 欧美激情一区二区在线| 亚洲一级黄色片| 欧美不卡视频一区| 国产亚洲福利社区一区| 亚洲乱码国产乱码精品精可以看 | 国产一区二区主播在线| 99精品视频一区| 久久免费黄色| 亚洲午夜精品久久久久久浪潮| 麻豆九一精品爱看视频在线观看免费| 国产精品成人观看视频免费| 亚洲成人影音| 久久久91精品国产| 日韩视频精品在线观看| 老牛国产精品一区的观看方式| 国产精品综合久久久| 一区二区三区免费在线观看| 欧美α欧美αv大片| 欧美一区二区三区视频在线观看 | 久久一日本道色综合久久| 亚洲香蕉网站| 欧美香蕉视频| 亚洲天堂免费观看| 最新热久久免费视频| 久久精品麻豆| 国产亚洲va综合人人澡精品| 亚洲午夜久久久久久久久电影院| 欧美福利视频在线观看| 久久不射网站| 国产偷久久久精品专区| 欧美激情 亚洲a∨综合| 亚洲国产导航| 亚洲成色777777在线观看影院 | 亚洲欧美激情一区二区| 亚洲欧洲一区二区三区久久| 美女主播视频一区| 亚洲第一福利在线观看| 国产欧美精品在线观看| 亚洲免费一在线| 亚洲视频一二区| 国产精品视频精品| 亚欧成人精品| 午夜精品久久久久影视| 国产精品嫩草久久久久| 亚洲欧美日韩电影| 亚洲午夜精品久久久久久浪潮| 国产精品美腿一区在线看| 亚洲欧美日韩国产综合| 亚洲一级高清| 黄色小说综合网站| 欧美不卡视频一区| 欧美二区视频| 亚洲中午字幕| 久久福利毛片| 亚洲人成人99网站| 日韩亚洲欧美在线观看| 国产精品久久一卡二卡| 久久精品亚洲一区二区| 久久精品72免费观看| 在线成人av网站| 亚洲人成毛片在线播放| 国产精品国产三级欧美二区 | 一区二区三区成人精品| 亚洲在线成人精品| 激情综合亚洲| 亚洲欧洲精品一区| 国产精品久久久久久亚洲调教| 久久激情中文| 欧美激情亚洲精品| 午夜精品视频在线观看一区二区| 久久久久久精| 亚洲一区二区精品视频| 欧美一级专区| 99精品免费| 欧美在线观看视频一区二区三区 | 欧美人成免费网站| 欧美一区二区三区日韩| 欧美高清在线视频| 久久一区免费| 国产精品入口| 亚洲国产一区二区精品专区| 国产精品一页| 99亚洲一区二区| 91久久精品网| 久久夜色精品一区| 欧美在线播放视频| 欧美日韩国产大片| 欧美国产亚洲精品久久久8v| 国产欧美一区二区三区久久人妖 | 最新热久久免费视频| 国产欧美精品久久| 亚洲高清不卡一区| 国产精品久久久久久久浪潮网站| 麻豆成人综合网| 国产精品久久久久久av福利软件 | 亚洲精品日本| 有坂深雪在线一区| 日韩视频一区二区三区| 亚洲电影第三页| 久久不射中文字幕| 久久国产精品毛片| 欧美日韩中文字幕精品| 亚洲第一主播视频| 国产一区二区三区最好精华液|