1. 程式人生 > 其它 >[c++] 面向物件課程(三)-- 面向物件模型

[c++] 面向物件課程(三)-- 面向物件模型

導讀

  • 模板/泛型,面向物件是C++的兩大思路
  • STL主要用模板/泛型

C++OOP2-ex.cpp

  1 // author : Hou Jie
  2 // date : 2015/11/27
  3 // compiler : DevC++ 5.11 (MinGW with GNU 4.9.2)
  4 // course : C++OOP2
  5 
  6 using namespace std;
  7 
  8 //-------------------------------------------------------------
  9 #include <string>
 10 #include <iostream>
 11
#include <memory> //shared_ptr 12 13 namespace jj01 14 { 15 class Base1 { }; 16 class Derived1: public Base1 { }; 17 class Base2 { }; 18 class Derived2: public Base2 { }; 19 20 21 template <class T1, class T2> 22 struct pair { 23 typedef T1 first_type; 24 typedef T2 second_type;
25 26 T1 first; 27 T2 second; 28 pair() : first(T1()), second(T2()) {} 29 pair(const T1& a, const T2& b) : first(a), second(b) {} 30 31 template <class U1, class U2> 32 pair(const pair<U1, U2>& p) : first(p.first), second(p.second) {} 33 }; 34 35 void
test_member_template() 36 { 37 cout << "test_member_template()" << endl; 38 pair<Derived1, Derived2> p; 39 pair<Base1, Base2> p2(pair<Derived1, Derived2>()); 40 pair<Base1, Base2> p3(p); 41 //Derived1 will be assigned to Base1; Derived2 will be assigned to Base2. 42 //OO allow such assignments since of "is-a" relationship between them. 43 44 //! pair<Derived1, Derived2> p4(p3); 45 //error messages as below appear at the ctor statements of pair member template 46 // [Error] no matching function for call to 'Derived1::Derived1(const Base1&)' 47 // [Error] no matching function for call to 'Derived2::Derived2(const Base2&)' 48 49 Base1* ptr = new Derived1; //up-cast 50 shared_ptr<Base1> sptr(new Derived1); //simulate up-cast 51 //Note: make sure your environment support C++2.0 at first. 52 } 53 } //namespace 54 //------------------------------------------------------------- 55 #include <string> 56 #include <iostream> 57 #include <list> 58 namespace jj02 59 { 60 template<typename T, 61 template <typename T> 62 class Container 63 > 64 class XCls 65 { 66 private: 67 Container<T> c; 68 public: 69 XCls() 70 { 71 for(long i=0; i< 100; ++i) 72 c.insert(c.end(), T()); 73 } 74 }; 75 76 template<typename T> 77 using Lst = list<T, allocator<T>>; //Note: make sure your environment support C++2.0 78 79 void test_template_template_parameters_1() 80 { 81 cout << "test_template_template_parameters_1()" << endl; 82 83 //! XCls<string, list> mylist; 84 //[Error] expected a template of type 'template<class T> class Container', got 'template<class _Tp, class _Alloc> class std::list' 85 XCls<string, Lst> mylist; //Note: make sure your environment support C++2.0 86 } 87 } //namespace 88 //------------------------------------------------------------- 89 #include <string> 90 #include <iostream> 91 #include <memory> //smart pointers 92 namespace jj03 93 { 94 template<typename T, 95 template <typename T> 96 class SmartPtr 97 > 98 class XCls 99 { 100 private: 101 SmartPtr<T> sp; 102 public: 103 XCls() : sp(new T) { } 104 }; 105 106 void test_template_template_parameters_2() 107 { 108 cout << "test_template_template_parameters_2()" << endl; 109 110 XCls<string, shared_ptr> p1; //Note: make sure your environment support C++2.0 111 XCls<double, auto_ptr> p4; 112 //! XCls<double, unique_ptr> p2; //unique_ptr has two template parameters 113 //! XCls<int, weak_ptr> p3; //[Error] no matching function for call to 'std::weak_ptr<int>::weak_ptr(int*)' 114 } 115 } //namespace 116 //------------------------------------------------------------- 117 #include <iostream> 118 namespace jj04 119 { 120 121 void test_object_model() 122 { 123 cout << "test_object_model()" << endl; 124 125 } 126 } //namespace 127 //------------------------------------------------------------- 128 #include <iostream> 129 namespace jj05 130 { 131 class Fraction 132 { 133 public: 134 explicit Fraction(int num, int den=1) 135 : m_numerator(num), m_denominator(den) 136 { cout << m_numerator << ' ' << m_denominator << endl; } 137 138 operator double() const { 139 return (double)m_numerator / m_denominator; 140 } 141 142 Fraction operator+(const Fraction& f) { 143 cout << "operator+(): " << f.m_numerator << ' ' << f.m_denominator << endl; 144 //... plus 145 return f; 146 } 147 /* 148 Fraction(double d) 149 : m_numerator(d * 1000), m_denominator(1000) 150 { cout << m_numerator << ' ' << m_denominator << endl; } 151 */ 152 153 private: 154 int m_numerator; // 155 int m_denominator; // 156 }; 157 158 void test_conversion_functions() 159 { 160 cout << "test_conversion_functions()" << endl; 161 162 Fraction f(3,5); 163 164 double d = 4 + f; //4.6 165 cout << d << endl; 166 167 //! Fraction d2 = f + 4; //ambiguous 168 } 169 } //namespace 170 //------------------------------------------------------------- 171 #include <iostream> 172 namespace jj06 173 { 174 void test_reference() 175 { 176 cout << "test_reference()" << endl; 177 178 { 179 int x=0; 180 int* p = &x; 181 int& r = x; //r is a reference to x. now r==x==0 182 int x2=5; 183 r = x2; //r cannot re-reference to another. now r==x==5 184 int& r2 = r; //now r2==5 (r2 is a reference to r, i.e. a reference to x) 185 } 186 187 188 { 189 typedef struct Stag { int a,b,c,d; } S; 190 191 double x=0; 192 double* p = &x; //p is a pointer to x. p's value is same as x's address. 193 double& r = x; //r is a reference to x, now r==x==0 194 195 cout << sizeof(x) << endl; //8 196 cout << sizeof(p) << endl; //4 197 cout << sizeof(r) << endl; //8 198 cout << p << endl; //0065FDFC 199 cout << *p << endl; //0 200 cout << x << endl; //0 201 cout << r << endl; //0 202 cout << &x << endl; //0065FDFC 203 cout << &r << endl; //0065FDFC 204 205 S s; 206 S& rs = s; 207 cout << sizeof(s) << endl; //16 208 cout << sizeof(rs) << endl; //16 209 cout << &s << endl; //0065FDE8 210 cout << &rs << endl; //0065FDE8 211 } 212 } 213 } //namespace 214 //------------------------------------------------------------- 215 int main(int argc, char** argv) 216 { 217 std::cout << __cplusplus << endl; //199711 or 201103 218 219 jj01::test_member_template(); 220 jj02::test_template_template_parameters_1(); 221 jj03::test_template_template_parameters_2(); 222 jj04::test_object_model(); 223 jj05::test_conversion_functions(); 224 jj06::test_reference(); 225 }
View Code

conversion function 轉換函式

  • 在運算時自動呼叫,把Fraction轉為double
  • 138:沒有返回型別,用double()表示
  • 139:double應寫在後面的括號裡,或者後面的括號不寫
  • 164:呼叫operator double() 將 f 轉為0.6
  • 《C++ Primer》 P514
 1 #include<iostream>
 2 using namespace std;
 3 
 4 class Complex{
 5     public:
 6         Complex():m_real(0.0),m_imag(0.0){}
 7         Complex(double real,double imag):m_real(real),m_imag(imag){}
 8         Complex(double real):m_real(real),m_imag(0.0){} //轉換建構函式 
 9     public:
10         friend ostream& operator << (ostream& out,Complex& c); //過載運算子 
11     private:
12         double m_real;
13         double m_imag;
14 };
15 
16 ostream & operator<<(ostream &out, Complex &c){
17     out<<c.m_real<<"+"<<c.m_imag<<"i";
18     return out;
19 }
20 
21 int main(){
22     Complex a = 25.5;
23     Complex b(10.0,20.0);
24     cout<<a<<endl; 
25     cout<<b<<endl; 
26     return 0;
27 }
View Code

參考

C++轉換函式

http://c.biancheng.net/view/2340.html