第1章 C++编程技术
/* 第一篇 预备知识 第1章 C++编程技术 1.1 类和对象 1.2 类的继承 1.3 函数重载 1.4 访问控制 1.5 操作符重载 1.6 显式类型转换 1.7 异常处理 1.8 名字空间 1.9 友员函数 1.10 内联函数 1.11 静态成员 1.12 本章小结 */ // 第一篇 预备知识 // 第1章 C++编程技术 // 1.1 类和对象 ------------------------------------------------------------------------------------------------------ // 晕,提供代码居然与书里的对不上的!自己输。 // p4 #include <iostream> using namespace std; //Compute.h文件 //因为是单文件调试,所以把头文件放到这里了 class CCompute{ protected: int i; int j; public: CCompute(int a,int b){ i=a; j=b; } ~CCompute(){} int sum(); int minus(); }; int CCompute::sum(){ return i+j; } int CCompute::minus(){ return i-j; } int main(){ CCompute computeObj(3,8); cout << "The sum is: " << computeObj.sum() << endl; cout << "The minus is: " << computeObj.minus() << endl; CCompute *pComputeObj=new CCompute(2,5); cout << "The sum is: " << pComputeObj->sum() << endl; cout << "The minus is: " << pComputeObj->minus() << endl; return 0; } // 1.2 类的继承 ------------------------------------------------------------------------------------------------------ // p5 #include <iostream> using namespace std; //Compute.h文件 //因为是单文件调试,所以把头文件放到这里了 class CCompute{ protected: int i; int j; public: CCompute(int a,int b){ i=a; j=b; } ~CCompute(){} int sum(); int minus(); }; int CCompute::sum(){ return i+j; } int CCompute::minus(){ return i-j; } // 继承类 class CCompute2:public CCompute{ public: CCompute2(int a,int b):CCompute(a,b){} // 调用基类构造函数 int mul(); // 添加自己的乘法函数 }; int CCompute2::mul(){ return i*j; } int main(){ CCompute2 compute2Obj(6,5); cout << "The mul is: " << compute2Obj.mul() << endl; return 0; } // 1.3 函数重载 ------------------------------------------------------------------------------------------------------ #include <iostream> using namespace std; // 基类 class CBase{ public: virtual void f(int x){ // 虚函数 cout << "CBase::f " << x << endl; } void g(float x){ // 木有 virtual cout << "CBase::g " << x << endl; } }; // 继承类 class CDerived:public CBase{ public: void f(int x){ cout << "CDerived::f " << x << endl; } void g(float x){ cout << "CDerived::g " << x << endl; } }; int main(){ CDerived DerivedObj; DerivedObj.f(3); // 继承类的f函数 DerivedObj.g(6.0f); // 继承类的g函数 // CBase *pBaseObj=&DerivedObj; pBaseObj->f(3); // 因为virtual了,执行继承类的f函数 pBaseObj->g(6.0f); // 因为木有virtual,执行的是基类的g函数 return 0; } // 1.4 访问控制 ------------------------------------------------------------------------------------------------------ // 1.5 操作符重载 ------------------------------------------------------------------------------------------------------ // p9 #include <iostream> using namespace std; class Complex{ private: double real; // 实数部分 double image; // 虚数部分 public: Complex(){} Complex(double a, double b){ real=a; image=b; } Complex operator+(Complex &c){ Complex tmp; // 因为要返回对象 tmp.real=c.real+real; tmp.image=c.image+image; return tmp; } Complex operator++(){ // 前缀++ 如++i real+=1; image+=1; return *this; } Complex operator++(int) { // 后缀++,如i++ 。int后不需要参数名,反正用不着。不过写上也木事 real+=10; // just for test,故意加10 image+=10; return *this; } void print(){ cout << real << " " << image << endl; } }; int main(){ Complex c1(3.6, 7.2); Complex c2(10.1, 20.3); Complex c3=c1+c2; // 调用 operator+ c3.print(); Complex c4=c1.operator+(c2); c4.print(); // 效果一样咯 ++c3; // 调用 operator++ c3.print(); c4++; // 调用 operator++(int) c4.print(); return 0; } // 1.6 显式类型转换 ------------------------------------------------------------------------------------------------------ // p10 #include <iostream> using namespace std; int main(){ double d(3.2); int i=static_cast<int>(d); cout << i << endl; return 0; } // reinterpret_cast #include <iostream> using namespace std; int main(){ double d(9.3); double *pd=&d; int *pi=reinterpret_cast<int*>(pd); cout << *pi << endl; cout << pd << " " << pi << endl; // 本身地址木有变,变的是指向类型。。 class A{}; class B{}; A* pa=new A; B* pb=reinterpret_cast<B*>(pa); long j=reinterpret_cast<long>(pi); // 把地址转换成了数 cout << j << endl; return 0; } // const_cast // p10-11 #include <iostream> using namespace std; int main(){ int i(3); const int *pci=&i; cout << ++i << endl; // 变量i本身可以改变。这里成4 // cout << ++(*pci) << endl; // error,常量指针指向的变量不能改变 int *pj=const_cast<int*>(pci); // 去除了指针变量的常量属性 cout << ++(*pj) << endl; // 所以这样就可以了,i成5 class A{}; const A* pca=new A; A *pa = const_cast<A*>(pca); cout << pa << endl; const int k(4); //int j=const_cast<int>(k); // error,想去除变量k的常数属性,不可以 //const int cj=const_cast<const int>(i); // 非指针转换,不可以 const int ck=(const int)i; // 隐式转换,可以 //++ck; // 改变常量ck,不可以 return 0; } // static_cast // p11 #include <iostream> using namespace std; int main(){ int i(0); double d=static_cast<double>(i); int j=static_cast<int>(d); class Base{}; class Derived:public Base{}; Derived d2; Base b=static_cast<Base>(d2); // Base b=(Base)d; // 继承类指针转换为基类指针,具有一定的危害性 Derived *pd=new Derived; Base *pb=static_cast<Base*>(pd); Base *pc=new Base; Derived *pe=static_cast<Derived*>(pc); return 0; } // dynamic_cast //略 // 1.7 异常处理 ------------------------------------------------------------------------------------------------------ // p14 guide中中文输出不正常,可在VC6中调试 #include <stdio.h> int main(void) { try { printf("try块1代码执行\n"); throw 10; // 因为抛出的是整数 } catch(int &i) // 所以这里被捕捉到了 { printf("处理try块1的int类型异常对象,值为%d\n", i); } catch(double d) { printf("处理try块1的double类型异常对象,值为%f\n", d); } // try { printf("try块2代码执行\n"); throw 23.8; } catch(int &i) { printf("处理try块2的int类型异常对象,值为%d\n", i); } catch(double d) { printf("处理try块2的double类型异常对象,值为%f\n", d); } // printf("程序结束\n"); return 0; } // p15 #include <stdio.h> int main(void) { try { int a = 0; int b = 32 / a; } catch(...) { //所有异常 printf("异常发生\n"); } return 0; } // p15 #include <stdio.h> class A { public: void f() { printf("函数f打印\n"); } void g() { throw 12; } }; int main(void) { A a; a.f(); //调用f try { a.g(); //调用g } catch(int &i) { printf("调用函数g出现运行异常,值为%d\n", i); } return 0; } // 后略 // 1.8 名字空间 ------------------------------------------------------------------------------------------------------ // p18 #include <stdio.h> namespace NS1 { int a = 1; } namespace NS2 { int a = 8; } int main(void) { printf("NS1名字空间定义的a值为%d\n", NS1::a); //打印a=1 printf("NS2名字空间定义的a值为%d\n", NS2::a); //打印a=8 return 0; } // p19 #include <stdio.h> namespace Myspace { int i = 1; int j = 3; } int main(void) { using namespace Myspace; i = j + 10; j = 20; printf("Myspace定义的变量i的值为%d\n", i); //打印13 printf("Myspace定义的变量j的值为%d\n", j); //打印20 return 0; } // 1.9 友员函数 ------------------------------------------------------------------------------------------------------ #include <stdio.h> class B; class A { bool bfinish; friend bool check(A a, B b); //声明check为类A的友员函数 public: A(bool b) { bfinish = true; } }; class B { bool bfinish; friend bool check(A a, B b); //声明check为类B的友员函数 public: B(bool b) { bfinish = b; } }; bool check(A a, B b) { //定义友员函数 if(a.bfinish && b.bfinish) return true; else return false; } int main(void) { A a(true); B b(false); if(check(a, b)) printf("bfinish都是true\n"); //调用友员函数 else printf("bfinish不都是true\n"); return 0; } // p21 #include <stdio.h> class B; class A { int i; public: A(int i_) { i = i_; } friend bool operator > (A &a, B &b); }; class B { double d; public: B(double d_) { d = d_; } friend bool operator > (A &a, B &b); }; bool operator > (A &a, B &b) { return a.i > b.d; } int main(void) { A a(19); B b(13.2); if(a > b) printf("a>b \n"); else printf("a<=b \n"); return 0; } // 1.10 内联函数 ------------------------------------------------------------------------------------------------------ // p22 #include <stdio.h> class A { int i; public: A(int i_) { i = i_; } //构造函数定义为内联函数 void print(); }; inline void A::print() { //print函数定义为内联函数 printf("i的值为%d\n", i); } int main(void) { A a(3); a.print(); return 0; } // 1.11 静态成员 ------------------------------------------------------------------------------------------------------ // p22-23 #include <stdio.h> class A { static int i; //声明为静态变量 static int j; int k; public: A(int k_) { k = k_; } static void setj(int j_); static void print_static(); void print(); }; int A::i = 10; //直接定义静态成员变量 int A::j; //必须先定义,再用函数初始化 void A::setj(int j_) { j = j_; } void A::print_static() { printf("静态成员变量i和j值为%d和%d\n", i, j); } void A::print() { printf("成员变量k的值为%d\n", k); } int main(void) { A::setj(20); A a(3); A::print_static(); //也可使用a.print_static()形式 a.print(); return 0; } // 1.12 本章小结