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

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>
            99这里有精品| 噜噜噜噜噜久久久久久91| 久久久www| 久久精品在线播放| 麻豆精品网站| 亚洲第一精品影视| 欧美一区二视频在线免费观看| 在线中文字幕一区| 一本色道久久99精品综合 | 久久国产精品高清| 久久久夜精品| 欧美国产日韩精品| 夜夜嗨av色综合久久久综合网| 一区二区三区精品| 久久成人国产精品| 欧美精品不卡| 国产精品盗摄久久久| 国产在线观看精品一区二区三区| 国产自产精品| 亚洲视频1区| 久久久久久999| 91久久精品国产91性色tv| 亚洲一区二区成人| 久久久噜噜噜久久中文字幕色伊伊| 欧美1区2区3区| 国产精品视频yy9099| 在线精品福利| 亚洲一区在线直播| 欧美福利电影网| 亚洲欧美激情四射在线日| 99精品欧美一区二区三区| 亚洲春色另类小说| 欧美一区二区三区日韩视频| 欧美日本高清视频| 国产一区二区三区直播精品电影 | 亚洲日韩欧美视频| 欧美一区二区在线观看| 欧美黑人在线播放| 国产日韩欧美夫妻视频在线观看| 亚洲精品色婷婷福利天堂| 性欧美8khd高清极品| 亚洲高清在线精品| 久久激情综合网| 国产精品蜜臀在线观看| 亚洲人成亚洲人成在线观看| 欧美综合77777色婷婷| 亚洲人成小说网站色在线| 久久精品伊人| 国产一区视频网站| 亚洲欧美一区二区视频| 亚洲精品精选| 免费日韩av片| 亚洲大片av| 久久久久久夜| 欧美一级免费视频| 国产精品久久久久久久久久免费看| 极品尤物一区二区三区| 欧美一级精品大片| 在线亚洲一区观看| 欧美日韩不卡一区| aa级大片欧美| 亚洲美女免费视频| 欧美精品精品一区| 99热精品在线| 欧美成人黄色小视频| 久久这里只有| 亚洲人成在线观看一区二区| 91久久久久久久久久久久久| 久久福利精品| 欧美影院午夜播放| 激情偷拍久久| 欧美a级片网站| 欧美mv日韩mv国产网站| 最新69国产成人精品视频免费| 久热精品视频在线观看| 久久精品在线观看| 亚洲精品黄色| 亚洲欧洲一区二区天堂久久| 欧美高清视频在线播放| 一区二区三区久久网| 亚洲欧洲日韩女同| 欧美网站在线观看| 亚洲欧美日韩国产一区| 欧美在线观看一区二区三区| 激情小说另类小说亚洲欧美| 亚洲第一主播视频| 欧美视频在线观看免费| 午夜精品视频在线| 欧美一区二区三区视频| 亚洲承认在线| 日韩亚洲欧美中文三级| 国产精品草草| 香蕉久久夜色精品国产| 欧美一区二区三区啪啪| 亚洲三级免费观看| 亚洲欧洲一级| 国产麻豆9l精品三级站| 免费欧美视频| 欧美高清一区| 亚洲免费影视第一页| 欧美在线一区二区| 国模一区二区三区| 欧美激情欧美狂野欧美精品| 欧美日韩亚洲精品内裤| 久久一二三四| 欧美性猛交xxxx免费看久久久| 久久综合中文字幕| 欧美婷婷久久| 欧美成人午夜激情在线| 欧美一区二区三区播放老司机| 在线观看欧美日韩| 在线中文字幕日韩| 国产日韩精品一区二区三区在线| 亚洲黄色av| 国产精品亚洲人在线观看| 免费成人av| 国产一区在线播放| 夜夜嗨一区二区| 亚洲精品免费看| 久久精品伊人| 欧美在线综合视频| 欧美性色综合| 亚洲毛片在线看| 亚洲欧洲午夜| 久久精品视频导航| 午夜综合激情| 国产精品初高中精品久久| 欧美激情va永久在线播放| 国产在线精品二区| 西瓜成人精品人成网站| 亚洲欧美国产精品专区久久| 欧美日韩精品国产| 亚洲欧洲偷拍精品| 一本到12不卡视频在线dvd| 老司机精品视频网站| 久久久久国产一区二区三区四区 | 国产视频一区二区三区在线观看| 亚洲乱码国产乱码精品精天堂| 最新亚洲视频| 久久久亚洲精品一区二区三区 | 久久性天堂网| 国内精品伊人久久久久av一坑| 亚洲网站视频福利| 欧美一区二区三区在线免费观看| 欧美视频在线观看视频极品| 99精品视频免费在线观看| 日韩香蕉视频| 欧美成人精品一区二区| 亚洲综合第一页| 国产精品日韩欧美一区二区三区 | 国产丝袜美腿一区二区三区| 性18欧美另类| 久久综合精品一区| 亚洲风情在线资源站| 免费在线亚洲欧美| 亚洲国产欧美日韩| 亚洲小视频在线观看| 国产精品综合久久久| 欧美在线观看www| 免费看的黄色欧美网站| 亚洲九九爱视频| 欧美日韩亚洲免费| 新狼窝色av性久久久久久| 欧美成人高清| 亚洲男同1069视频| 影音先锋亚洲电影| 欧美黄色日本| 亚洲视频电影图片偷拍一区| 久久精品国产久精国产思思| 在线观看一区| 欧美日韩精品三区| 欧美在线观看视频在线 | 亚洲欧美日韩视频二区| 国产麻豆成人精品| 免费观看亚洲视频大全| 亚洲性图久久| 免费在线国产精品| 亚洲午夜女主播在线直播| 国产一区二区精品在线观看| 久久久久这里只有精品| aⅴ色国产欧美| 久久国产精品亚洲77777| 亚洲破处大片| 国产亚洲精品一区二区| 麻豆精品视频在线| 亚洲综合久久久久| 亚洲第一久久影院| 欧美在线视频不卡| 99国产精品久久久久久久成人热| 久久综合九九| 亚洲欧美乱综合| 欧美国产在线视频| 欧美一区二区视频网站| 一本色道**综合亚洲精品蜜桃冫| 国内精品久久久久影院 日本资源 国内精品久久久久伊人av | 国产欧美日韩一区二区三区在线观看 | 亚洲国产精品成人综合色在线婷婷| 欧美日韩成人综合天天影院| 久久国产精品网站| 亚洲欧美春色|