[C++]from C to C++(grammar)

本文,直接记录在从C转到C++学习的过程中,了解与区分的语法差异。用于高速补全C++语法点知识,无需参考百科全书。

备注:
  1. 为了达成“速成”的效果,采用菜鸟教程,链接
  2. 结合《Essential C++》来学习。
当然,所谓的速成,仅仅是说从C到C++的语法补充,而不是速成C++,绝对不是这个意思。

C++ 基本语法

C++ 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。
  1. 对象 - 对象具有状态和行为。例如:一只狗的状态 - 颜色、名称、品种,行为 - 摇动、叫唤、吃。对象是类的实例。
  2. 类 - 类可以定义为描述对象行为/状态的模板/蓝图。
  3. 方法 - 从基本上说,一个方法表示一种行为。一个类可以包含多个方法。可以在方法中写入逻辑、操作数据以及执行所有的动作。
  4. 即时变量 - 每个对象都有其独特的即时变量。对象的状态是由这些即时变量的值创建的。
 
命名空间

一般程序,都应该包含namespace std这个命名空间,最常用。
命令行下,执行
$ grep -n "namespace std" /usr/include/c++/6/*
即可发现,std命名空间已经包含非常多内容了。其中包含了标准C,STL等。

引用(reference)与指针(pointer)

指针的算术运算:关键在于,理解指针递增/递减的字节数。或者可以从对象的内存大小理解。
C++的引用与指针,三个区别: 链接
  1. 不存在空引用,引用必须链接到一块合法内存,指针可以指向NULL。
  2. 引用不允许改变所代表的对象,指针可以随时修改指向。
  3. 引用必须在创建时被初始化,指针可以随时被初始化。
使用引用原因:
  1. 希望得以直接对传入的对象进行修改。
  2. 降低复制大型对象的格外负担(效率问题)。
引用作为返回值, 链接

函数参数的默认值(默认参数值)

使用规则:
  1. 待设置默认值的参数不能是reference(无法被设置为0,一定需指定对象),可以是pointer。
  2. 默认值的解析(resolve)操作由最右开始进行。也就某参数提供默认值的右边的所有参数都应该有默认值。
  3. 默认值只能指定一次,可在函数定义处,可在函数声明处。(为了更高的可见性,将默认值放在函数声明处)
当调用函数时,具备默认值的参数为空,则采用默认值;如果指定了参数的值,则忽略默认值。

函数重载与使用模板

使用场景:
  1. 重载(overlord),其每份实例提供的是相同的通用服务。
  2. 程序代码的主体不变,仅仅改变其中用到的数据类型,可以使用模板。
  3. 两者结合使用(STL库的根基)。


一个空类,编译器自动定义:构造、析构、拷贝构造、赋值(赋值运算符): [笔记]C++的空类
类访问修饰符 类成员可以被定义为 public、private 或 protected。默认情况下是定义为 private。
构造函数&析构函数 类的构造函数是一种特殊的函数,在创建一个新的对象时调用。类的析构函数也是一种特殊的函数,在删除所创建的对象时调用。
拷贝构造函数 拷贝构造函数,是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。
友元函数 友元函数可以访问类的 private 和 protected 成员。(并不是类的成员函数,也可以是友元类,不止是函数)
this指针 每个对象都有一个特殊的指针 this,它指向对象本身。(仅成员函数有this指针,友元函数没有)
指向类的指针 指向类的指针方式如同指向结构的指针。实际上,类可以看成是一个带有函数的结构。
类的静态成员 类的数据成员和函数成员都可以被声明为静态的。(类的所有实例仅一份副本并共享之,创建第一实例时,所有静态成员都为零,并不能在类的定义中(个人理解为析构函数中))

重载运算符和重载函数

重载函数:参数列表和定义(实现方法不同),但提供相同的服务(函数名相同)。编译器会自动进行重载决策(无法通过返回值进行决策)。
重载运算符:
  1. 重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
  2. 可以重定义或重载大部分 C++ 内置的运算符。这样,就能使用自定义类型的运算符。
实现注意:可重载运算符、不可重载运算符
运算符重载实例:
  1. 一元运算符重载
  2. 二元运算符重载
  3. 关系运算符重载:==和!=可以配置使用
  4. 输入/输出运算符重载
  5. ++ 和 -- 运算符重载
  6. 赋值运算符重载
  7. 函数调用运算符 () 重载
  8. 下标运算符 [] 重载
  9. 类成员访问运算符 -> 重载

构造类class

构造函数constructor与析构函数
constructor:
  1. constructor必须与class同名
  2. constructor不应指定返回值,也没有返回类型,允许有参数
  3. 可overload
  4. initialize stype:
    1. constructor内赋值
    2. constructor成员初始化列表
  5. object实例化时被调用
Triangular::Triangular(int len, int bp)
     :_name("Triangular")
{
     _length = len > 0 ? len : 1;
     _beg_pos = bp > 0 ? bp : 1;
     _next = _beg_pos - 1;
}
destructor:
  1. destructor必须与class同名,并前面条件‘~’前缀
  2. destructor没有返回值,也没有返回类型,同时也没有参数
  3. object被销毁时自动调用
  4. 并非必须,程序设计时根据需要可以省略
注意,易出错:
  1. 成员逐一初始化

可变(mutable)与不可变(const)

     编译器不会对每个函数进行分析,决定它究竟是const还是non-const,但它会检查每个声明为const的member function,看看它们是否真的没有更改class object的内容,如果修改了则编译出错。
int sum(const Triangular &trian)
{
     int beg_pos = trian.beg_pos();
     int length = trian.length();
     int sum = 0;
     for(int ix=0; ix < length; ++ix)
          sum += trian.elem(beg_pos+ix);
     return sum;
}
分析:函数输入const,但调用三个class成员函数是可能会改变class的状态值(成员值/成员变量)
class val_class
{
     public:
          const BigClass& val() const {return _val;}//const version
          BigClass& val() {return _val;}//non-const version
}

void example(const BigClass *pbc, BigClass &rbc)
{
     pbc->val();//call const version
     rbv.val();//call non-const version
}
分析:根据参数类型(const、non-const),编译器选择调用不同version

继承与多态

简要总结
  1. 继承:使我们得以将一群相关的类组织起来,并让我们得以分享其中的共通数据和操作行为。
  2. 多态:让我们在这些类之上进行编程时,可以如同操控一个单体,而非相互独立的类,并赋予我们更多弹性来加入或移除任何特定类。

最简总结
  1. 继承:享有共通的接口。
  2. 多态:得以用一种类型无关(type-independent)的方式来操作这些对象。

机制实现
  1. 继承机制:定义了父子关系。父类定义了所有子类共通的公有接口和私有实现。每个子类都可以增加或覆盖继承而来的东西,以实现自身独特的行为。
    1. 父类为基类,子类为派生类,父类与子类之间的关系称之为继承体系。
    2. 间接利用指向抽象基类的pointer和reference来操作系统中的各对象,而不是直接操作各个对象。
    3. 主要研究:基类的实现方法被子类继承后,如何被解析(也就如何工作的)
  2. 多态:让基类的pointer或reference得以十分透明地(transparently)指向其中任何一个派生类的对象。其中,这种指向,是又动态绑定(dynamic binding)实现的,“找出基类pointer或reference实际被调用的究竟是哪一个派生类的函数”这一解析操作会延迟至运行时(run-time)才被执行。
    1. 也就是调用基类提供的虚函数接口,实际上被解析为某派生类的具体实现方法。

机制解析
  1. 虚函数机制:

主要解决问题:
  1. 根据经验,思考派生类的操作函数将在何时被解析为(基类/派生类的实现方式)
    1. 通过虚函数机制,动态绑定,解析为派生类实现方式
    2. 通过对象(pointer、reference的类型),静态解析,解析可能为基类或派生类

抽象基类的设计步骤:
  1. 找出所有子类的共通的操作行为。设计出基类的公有接口(public interface)。
  2. 找出那些操作行为与类型有关(tepe-dependent),有哪些操作行为必须根据不同的派生类而有不同的实现方式。这些操作行为应该成为整个类的继承体系中的虚函数。
    1. static member function无法被声明为虚拟函数。
  3. 试着找出每个操作行为的访问层级(access level)。
    1. public:一般程序能够访问的。
    2. private:基类之外不会被使用到的。
    3. protected:可让派生类访问,却不允许一般程序使用。
备注:当我们面临“萃取基类和派生类之间的性质,以决定哪些东西(包括接口和实际成员)属于”谁“时,面向对象设计所面对的挑战,将不只是编程层面而已。这是一个迭代的过程,借由程序设计的经验和用户的反馈,不断演进。




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GreenCppC 2008-8-24 ========================================= // I 类,对象,函数重载 //-------- From C to C++ ------------ // A simple C Program! // convert a string to uppercase! #include <stdio.h> #define N 200 int main(){ char ms[N]; int i; printf("Input ms: "); gets(ms); for(i=0;ms[i];i++) if(ms[i]>='a'&&ms[i]<='z') ms[i]-='\x20'; puts(ms); return 0; } /* path d:\wingw\bin gcc abc.c -o abc.exe */ //------------------------------ // A better C Program! #include <stdio.h> #define N 200 void strUpper(char *s); void strLower(char *s); int main(){ char ms[N]; printf("Input ms: "); gets(ms); strUpper(ms); puts(ms); strLower(ms); puts(ms); return 0; } void strUpper(char *s) { for(;*s;s++) if(*s>='a'&&*s<='z')*s-='\x20'; } void strLower(char *s) { for(;*s;s++) if(*s>='A'&&*s<='Z')*s+='\x20'; } //------------------------------ // A C++ Program without class and object! #include <iostream> using namespace std; const int N=200; void strUpper(char *s); void strLower(char *s); int main(){ char ms[N]; cout<<"Input ms: "; cin.getline(ms,N); strUpper(ms); cout<<ms<<"\n"; strLower(ms); cout<<ms<<endl; return 0; } void strUpper(char *s) { for(;*s;s++) if(*s>='a'&&*s<='z')*s-='\x20'; } void strLower(char *s) { for(;*s;s++) if(*s>='A'&&*s<='Z')*s+='\x20'; } //------------------------------ // A C++ Program with class and object! #include <iostream> using namespace std; const int N=200; class Str{ char s[N]; public: void out(){cout<<s<<"\n";} void in(){cout<<"s: "; cin.getline(s,N);} void upper(); void lower(); }; void Str::upper() {char *p; for(p=s;*p;p++) if(*p>='a'&&*p<='z')*p-='\x20'; } void Str::lower() { for(char *p=s;*p;p++) if(*p>='A'&&*p<='Z')*p+='\x20'; } // - - - int main(){ Str a; cin>>a.s; //error! a.in(); a.upper(); a.out(); a.lower(); a.out(); return 0; } ========================================= // II. 构造与析构函数 #include <iostream> #include <cstring> using namespace std; class child { char name[20]; int age; public: child(); child(char *n,int a); void ask(char *n); void ask(int a); ~child(); }; // --- child::child(){ strcpy(name,"Tomme"); age=3; } // --- child::child(char *name,int age){ strcpy(this->name,name); this->age=age; // this -- address of self object } // --- void child::ask(char *n){ if(!strcmp(name,n)) cout<<"Yes, i am "<<n<<".\n"; else cout<<"No, i am not "<<n<<".\n"; } // --- void child::ask(int age){ if(this->age==age) cout<<"Yes, i am "<<age<<" years old.\n"; else cout<<"No, i am not "<<age<<" years old.\n"; } // --- child::~child(){ cout<<name<<": Bye!\n"; } //---------- int main(){ child tom,rose("Rosie",4); tom.age=4; // error! tom.ask("tom"); rose.ask("Alice"); tom.ask(2); return 0; } ========================================= // III. 继承 #include <iostream> #include <cstring> using namespace std; class child { protected: //note this change! char name[20]; int age; public: child(); child(char *n,int a); void ask(char *n); void ask(int a); }; // --- child::child(){ strcpy(name,"Tomme"); age=3; } // --- child::child(char *n,int a){ strcpy(name,n); age=a; } // --- void child::ask(char *n){ if(!strcmp(name,n)) cout<<"Yes, i am "<<n<<".\n"; else cout<<"No, i am not "<<n<<".\n"; } // --- void child::ask(int a){ if(a==age) cout<<"Yes, i am "<<a<<" years old.\n"; else cout<<"No, i am not "<<a<<" years old.\n"; } // ----------- class pupil: public child{ char book[20]; public: pupil(char *n,int a,char *b); void list(); }; // --- pupil::pupil(char *n,int a,char *b): child(n,a) { strcpy(book,b); } // --- void pupil::list() { cout<<name<<" "<<age<<" "<<book<<"\n"; } //---------- int main(){ child tom,rose("Rosie",4); tom.ask("tom"); rose.ask("Alice"); tom.ask(2); pupil green("Green",9,"Nature"); green.ask("Jack"); green.ask(10); green.list(); return 0; } ========================================= // IV. 增加与基类成员函数同名的函数; // 调用基类成员函数;内联函数(in-line) #include <iostream> #include <cstring> using namespace std; class child { protected: char name[20]; int age; public: child(); child(char *n,int a); void ask(char *n); void ask(int a); }; // --- child::child(){ strcpy(name,"Tomme"); age=3; } // --- child::child(char *n,int a){ strcpy(name,n); age=a; } // --- void child::ask(char *n){ if(!strcmp(name,n)) cout<<"Yes, i am "<<n<<".\n"; else cout<<"No, i am not "<<n<<".\n"; } // --- void child::ask(int a){ if(a==age) cout<<"Yes, i am "<<a<<" years old.\n"; else cout<<"No, i am not "<<a<<" years old.\n"; } // ----------- class pupil: public child{ char book[20]; public: pupil(char *n,int a,char *b); void ask(char *n){child::ask(n);} // in-line! void ask(int a){child::ask(a);} void ask(); }; // --- pupil::pupil(char *n,int a,char *b): child(n,a) { strcpy(book,b); } // --- void pupil::ask() { cout<<name<<" "<<age<<" "<<book<<"\n"; } //---------- int main(){ child tom,rose("Rosie",4); tom.ask("tom"); rose.ask("Alice"); tom.ask(2); pupil green("Green",9,"Nature"); green.ask("Jack"); green.ask(10); green.ask(); return 0; } ===================================== // V. 对象数组 #include <iostream> using namespace std; class C1{ int a,b; public: C1(int m,int n){a=m;b=n;} int getAdd(){return a+b;} }; int main() {C1 ob[3]={C1(1,2),C1(3,4),C1(5,6)}; int i; for(i=0;i<3;i++) cout << ob[i].getAdd() << " "; // C1 oe[2]; -- Error! means constructor is C1() // -- need reload C1::C1(){ ... } // -- eg, C1::C1(){a=b=0;} return 0; } ========================================= // VI. 指向对象的指针 C1 obA(2,3), *p; p=&obA; cout << p->getAdd(); //------------- C1 ob[3]={C1(1,2),C1(3,4),C1(5,6)}, *q; q=ob; for(int i=0;i<3;i++) {cout << q->getAdd() << " "; q++; } //------------- class C2{ public: int a; C2(int k){a=k*k;} }; // . . . C2 obB(9); int *p; p=&obB.a; // Note! a is public, p to member cout << *p; // 指向派生类的指针 class Base{ public: int a,b; Base(int m,int n){a=m;b=n;} int getAdd(){return a+b;} }; class Derived: public Base{ int c; public: Derived(int x,int y,int z): Base(x,y) {c=z;} float getAve(){return (a+b+c)/3.0F;} }; // ... Base *bp; Derived d(6,7,9); bp=&d; cout << bp->getAdd(); cout << bp->getAve(); // Error! cout << ((Derived *) bp) ->getAve(); ========================================= // VII. 动态分配:new, delete #include <iostream> #include <new> using namespace std; int main() {int *p; try{ p=new int; } catch(bad_alloc ex){ cout << "New failed!\n"; return -1; } *p=20; cout << "At "<<p<<" is "<< *p <<"\n"; delete p; return 0; } //------------- #include <iostream> #include <new> using namespace std; int main() {int *p; try{ p=new int[6]; } catch(bad_alloc ex){ cout << "New failed!\n"; return -1; } float ave=0.0F; int i; cout<<"Enter numbers: "; for(i=0;i<6;i++) {cin>>p[i]; ave+= *(p+i); cout<< *(p+i); } ave/=6.0F; cout << "Ave = "<< ave <<"\n"; delete [] p; return 0; } //------------- #include <iostream> #include <cstring> #include <new> using namespace std; class Balance{ char name[40]; double curValue; public: Balance(char *n,double v){ strcpy(name,n); curValue=v; } void getValue(char *n,double &v){ strcpy(n,name); v=curValue; } }; int main() { Balance *p; char s[40]; double bal; try{ p=new Balance("Robin Hood",3536.45); } catch(bad_alloc ex){ cout << "New failed!\n"; return -1; } p->getValue(s,bal); cout<<s<<"\'s balance is "<<bal<<"\n"; delete p; return 0; } ========================================= // VIII. 传递引用 #include <iostream> using namespace std; void neg1(int k); void neg2(int *p); void neg3(int &k); int main() { int x=20; neg1(x); neg2(&x); cout << x<< "\n"; neg3(x); cout << x<< "\n"; } // - - - void neg1(int k) { k=-k;} void neg2(int *p) { *p=-*p;} void neg3(int &k) { k=-k; } //------------- #include <iostream> using namespace std; class C1{ public: int k; void neg(C1 &o){o.k=-o.k;} // -- no temp object created }; int main() { C1 ob; ob.k=20; ob.neg(ob); cout << ob.k <<"\n"; return 0; } //----------------------------------- /* Input a sentence,reverse all the words except other chars, eg: etihw, dna kcalb! => white, and black! NOT: !black and ,white */ #include <iostream> #include <new> #include <cstdlib> #include <cctype> using namespace std; const int N=200; /* - - - - - - */ class CharStack{ const int StkLen; char *data; int top; public: CharStack(); ~CharStack(){delete []data;} int push(char x) {if(top>=StkLen-1)return -1; // it's full top++; data[top]=x; return 0; } int pop(char &x) {if(top<=-1)return -1; // empty! x= *(data+top); top--; return 0; } }; CharStack::CharStack():StkLen(40) {try{ data=new char[StkLen]; }catch(bad_alloc){cout<<"New failed!"; exit(-1);} top=-1; } // --------- class WordRev{ char ms[N]; public: void reads() { cout<<"Input str:\n"; cin.getline(ms,N); } void prints() { cout<<ms<<"\n"; } void wRev(); }; void WordRev::wRev() {CharStack stk; int i=0,wStart,wEnd; while(ms[i]) {if(!isalpha(ms[i]))i++; else {wStart=i; while(isalpha(ms[i]))stk.push(ms[i++]); wEnd=i; i=wStart; while(!stk.pop(ms[i]))i++; i=wEnd; } } } // --------- int main() { WordRev sr; sr.reads(); sr.wRev(); sr.prints(); return 0; } ========================================= // IX 函数形参使用默认值 #include <iostream> #include <cstring> using namespace std; // ----------- class pupil{ public: char name[20]; int age; char book[20]; pupil(char *n,int a,char *b); void list(); }; // --- pupil::pupil(char *n,int a,char *b){ strcpy(name,n); age=a; strcpy(book,b); } // --- void pupil::list() { cout<<name<<" "<<age<<" "<<book<<"\n"; } //---------- void nextYear(pupil &c,char *book="Math"); //---------- int main(){ pupil green("Green",9,"Chinese"); green.list(); nextYear(green); green.list(); nextYear(green,"Nature"); green.list(); return 0; } //---------- void nextYear(pupil &c,char *book="Math") { // ="Math" Should be omitted, for previous prototype c.age++; strcpy(c.book,book); return; } /* D:\green>g++ pupil.cpp -o pupil.exe pupil.cpp: In function `void nextYear(pupil&, char*)': pupil.cpp:41: error: default argument given for parameter 2 of `void nextYear(pupil&, char*)' pupil.cpp:25: error: after previous specification in `void nextYear(pupil&, char*)' */ ========================================= // X. 虚函数 virtual #include <iostream> using namespace std; class base{ public: virtual void vf(){cout<<"base's vf.\n";} }; class derived1:public base{ public: virtual void vf(){cout<<"derived1's vf.\n";} }; class derived2:public base{ public: virtual void vf(){cout<<"derived2's vf.\n";} }; void f(base &r){r.vf();} int main() {base b, *p; derived1 d1; derived2 d2; b.vf(); d1.vf(); d2.vf(); p=&b; p->vf(); p=&d1; p->vf(); // derived1's vf. p=&d2; p->vf(); // derived2's vf. f(b); f(d1); // derived1's vf. f(d2); // derived2's vf. return 0; } ========================================= // XI. 对象赋值问题 #include <iostream> #include <cstdlib> #include <new> using namespace std; class Myclass{ int *p; public: Myclass(int i); void show(){cout<< *p<<"\n";} ~Myclass(){delete p;} }; Myclass::Myclass(int i){ try{ p=new int; } catch(bad_alloc e) {cout<< "New failed!\n"; exit(-1); } *p=i; } int main() {Myclass a(20); Myclass b=a; //copy by bits b.show(); return 0; // 错误!对象中 p 所指向的内存空间将被释放 2 次! } ========================================= // XII. 拷贝构造函数 ---- 解决对象参数传递的副作用问题 #include <iostream> #include <new> using namespace std; class array{ public: int *p; int size; array( ){p=NULL;size=0; }; array(int sz); array(const array &a); ~array(){if(!p){delete [ ]p; size=0;}} void input(); }; array::array(int sz){ size=sz; try{ p=new int[size]; }catch (bad_alloc xa){ cout <<"Alloc failed!"; exit(EXIT_FAILURE); } } array::array(const array &a){ try{ p=new int[a.size]; }catch (bad_alloc xa){ cout <<"Alloc failed!"; exit(EXIT_FAILURE); } size=a.size; for(int i=0;i<size;i++)p[i]=a.p[i]; } void array::input(){ cout<<"Input "<<size<<" integers: "; for(int i=0;i<size;i++)cin>>p[i]; } void inc(array a){ int i; for(i=0;i<a.size;i++) if(a.p[i]==59)a.p[i]++; cout<<"Result is: " ; for(i=0;i<a.size;i++)cout<<a.p[i]<<' '; cout<<"\n"; } int main(){ array a(4),c; a.input(); array b(a); // 调用拷贝构造函数 inc(b); //调用拷贝构造函数(隐式) for(int i=0;i<b.size;i++)cout<<b.p[i]<<' '; return 0; } ========================================= // XIII. 运算符重载 #include <iostream> using namespace std; class loc{ int longitude,latitude; public: loc(){} //needed to construct temp objects loc(int lg,int lt){longitude=lg; latitude=lt;} void show(){cout<<longitude<<" "<<latitude<<"\n";} loc operator+(loc op2); loc operator++(); loc operator=(loc op2); loc operator+=(loc op2); }; loc loc::operator+(loc op2) {loc temp; temp.longitude=op2.longitude+longitude; temp.latitude=op2.latitude+latitude; return temp; } loc loc::operator++() //前缀形式 prefix {longitude++; latitude++; return *this; } loc loc::operator=(loc op2) { longitude=op2.longitude; latitude=op2.latitude; return *this; //为连续赋值 } loc loc::operator+=(loc op2) { longigude=op2.longitude+longitude; latitude=op2.latitude+latitude; return *this; //为连续赋值 } // operator=和operator++等都改变了对象的值 int main() {loc ob1(10,20),ob2(5,30),ob3; ob3=ob1+ob2; ++ob3; ob3.show(); ob1+=ob2; ob1=ob1+ob2; // ob1.+(ob2) like (ob1+ob2).show(); ++ob1; ob1=ob2=ob3; ... ... } ========================================= // XIV. 异常的抛出,捕获与处理 #include <iostream> using namespace std; int main() {cout <<"Start\n"; try { cout << "Inside try block\n"; throw 100; cout << "This will not execute"; } catch (int i) { cout << "Caught an exception, value is: "; cout << i <<"\n"; } cout << "End\n"; return 0; } // -------------------- #include <iostream> using namespace std; void xtest(int test) { cout << "Inside xtest!\n"; if(test) throw test; } int main() {cout <<"Start\n"; try { cout << "Inside try block\n"; xtest(0); xtest(1); xtest(2); } catch (int i) { cout << "Caught an exception, value is: "; cout << i <<"\n"; } cout << "End\n"; return 0; } // 捕获异常类 #include <iostream> #include <cstring> using namespace std; class MyException{ public: char how[80]; int what; MyException(){*how=0; what=0;} MyException(char *s, int n) {strcpy(how,s); what=n; } }; int main() {int i; try { cout <<"Enter a positive number: "; cin >> i; if(i<0) throw MyException("Not Positive",i); } catch (MyException e) { cout << e.how<<": "; cout << e.what <<"\n"; } return 0; } // 捕获派生异常类 #include <iostream> using namespace std; class B { }; class D: public B { }; int main() {D derived; try { throw derived; } catch (D d) { cout << "Caught a derived class, not the base! \n"; } catch (B b) { cout << "Caught the base class! \n"; } return 0; } // 异常的限制及捕获所有异常 #include <iostream> using namespace std; void xtest(int test) throw (int,char,double,char *) { try { if(test==0) throw test; if(test==1) throw 'a'; if(test==2) throw 12.34; if(test==3) throw "A string."; } catch (int i) { cout << "Caught an integer!"; } catch (...) { cout << "Caught Another!"; } } int main() {cout <<"Start\n"; xtest(0); xtest(1); xtest(2); xtest(3); cout << "End\n"; return 0; } // 异常的再次抛出 #include <iostream> using namespace std; void xhandler() { try { throw "Hello!"; } catch (const char *) { cout << "Caught a string inside!\n"; throw; //rethrow char * out of function } } int main() {cout <<"Start\n"; try { xhandler(); } catch (const char *) { cout << "Caught a string outside!\n"; } cout << "End\n"; return 0; } // 一个简单的程序 #include <iostream> using namespace std; int main() {int a,b; cout <<"Enter a b: "; cin >> a >> b; try { if(!b) throw b; cout << "Result: "<< a/b << endl; } catch (int i) { cout << "Can't divide by zero!\n"; } return 0; } ========================================= XV. 模板 //模板之通用函数 #include <iostream> using namespace std; template <class X> void superSwap(X &a, X &b) { X t; t=a; a=b; b=t; }; int main() { int m=10, n=20; double x=10.1, y=20.2; char a='A', b='\x42'; superSwap(m,n); superSwap(x,y); superSwap(a,b); cout<<"m="<<m<<", n="<<n<<'\n'; cout<<"x="<<x<<", y="<<y<<'\n'; cout<<"a="<<a<<", b="<<b<<'\n'; return 0; } ---------------------------------- #include <iostream> using namespace std; template <class type1,class type2> void myfunc(type1 x, type2 y) { cout<<x<<' '<<y<<'\n'; } int main() { myfunc("C++ is great!", 100); // char* , int myfunc(1234.56, 20L); // double , long int return 0; } // 模板之通用类 #include <iostream> using namespace std; const int Size=20; template <class DataType> class SuperStack{ DataType data[Size]; int top; public: SuperStack(){top= -1;} int push(DataType x); int pop(DataType &x); }; template <class DataType> int SuperStack<DataType>::push(DataType x) { if(top>=Size-1) return -1; // stack is full data[++top]=x; return 0; } template <class DataType> int SuperStack<DataType>::pop(DataType &x) { if(top<0) return -1; // stack is empty x=data[top--]; return 0; } int main() { SuperStack<char> chStack; SuperStack<double> dbStack; char s[Size]="ABC"; double a[Size]={20.1, 21.2, 22.3}; int i; for(i=0;i<3;i++) { chStack.push(s[i]); dbStack.push(a[i]); } for(i=0;i<3;i++) { chStack.pop(s[i]); dbStack.pop(a[i]); } cout << s << '\n'; for(i=0;i<3;i++) cout << a[i]<<' '; cout<<'\n'; return 0; } ========================================= XVI. 名字空间 #include <iostream> using namespace std; namespace GreenNamespace{ char Say[80]="TRUTH, Must thou Know!"; bool isUpperLetter(char ch) { if(ch>='A' &&ch<='Z')return true; return false; } class X{ public: int year; X(int y){year=y;} }; // note this semi-colon! } using namespace GreenNamespace; int main() {cout << Say <<'\n'; char *p=Say; int count=0; for(;*p;p++) if(isUpperLetter(*p))count++; cout << "count = " << count <<'\n'; X ob(2006); cout << ob.year <<"\n"; return 0; } //------------------------ ////////// OneCount.cpp//////// namespace BitsSpace{ int onePerByte(char x); int oneCount(char *buf,int bytes); // ------------------- int onePerByte(char x) {int count=0,i; for(i=0;i<8;i++) {if(x & '\x1') count++; // 'A'<=> '\x41' x>>=1; //x=x>>1; } return count; } // --- int oneCount(char *buf,int bytes) {int count=0,i; for(i=0;i<bytes;i++) count+=onePerByte(buf[i]); return count; } // --- } ---------------- ////////// testOne.cpp//////// #include <iostream> #include "OneCount.cpp" using namespace std; //using namespace BitsSpace; const int SLen=80; // ---- int main(){ char ms[SLen],*p; cout<<"Enter your words:\n> " ; cin.getline(ms,SLen); cout<< BitsSpace::oneCount(ms,strlen(ms))<<"\n"; cout<<"Size of char: "<<sizeof(char)<<"\n"; return 0; } ========================================= //////////////////////////////// // XVII. C++ file handle, 6 programs // by Hs.li 2007.4.28 //////////////////////////////// // Write text strings! #include <iostream> #include <fstream> using namespace std; #define MaxN 200 // - - - - - - int main() {fstream outF; char text[MaxN]; cout<<"Enter lines, end with empty line:\n"; outF.open("str.txt",ios::out); if(!outF.is_open()) {cout<<"File open failed!\n"; return -1; } while(1) { cin.getline(text,MaxN); if(!text[0])break; outF<<text<<"\n"; if(outF.bad()||outF.fail()) {cout<<"Write file error!\n"; outF.close(); return -2; } } cout<<"Write text file okey!\n"; outF.close(); return 0; } ========================= // Read text strings! #include <iostream> #include <fstream> using namespace std; #define MaxN 200 // - - - - - - int main() {fstream inF; char text[MaxN]; cout<<"The text lines are:\n"; inF.open("str.txt",ios::in); if(!inF.is_open()) {cout<<"File open failed!\n"; return -1; } while(1) { inF.getline(text,MaxN); if(inF.eof()|inF.fail()|inF.bad())break; cout<<text<<"\n"; } if(!inF.eof()) {cout<<"Read file error!\n"; inF.close(); return -2; } cout<<"---- End!\n"; inF.close(); return 0; } ====================== // Write text data! #include <iostream> #include <fstream> using namespace std; // - - - - - - int main() { const int MaxN=8; fstream outF; double a[MaxN]; char *fname="data.txt"; int i; cout<<"Please input 8 double: "; for(i=0;i<MaxN;i++) cin>>a[i]; outF.open(fname,ios::out); if(!outF.is_open()) {cout<<"File open failed!\n"; return -1; } outF.exceptions(fstream::failbit| fstream::badbit); try{ for(i=0;i<MaxN;i++) outF<<a[i]<<" "; } catch(std::exception &e) {cout<<"Exception caught:"<<e.what()<<endl; outF.close(); return -2; } outF.close(); cout<<"Text data file write okey!\n"; return 0; } ============================ // Read text data! #include <iostream> #include <fstream> using namespace std; // - - - - - - int main() { fstream inF; double b; char *fname="data.txt"; cout<<"Please wait for reading data:\n"; inF.open(fname,ios::in); if(!inF.is_open()) {cout<<"File open failed!\n"; return -1; } inF.exceptions(fstream::failbit| fstream::badbit|fstream::eofbit); try{ while(1) { inF>>b; cout<<b<<" "; } }catch(std::exception &e) { if(!inF.eof()) { cout<<"Exception caught:"<<e.what()<<endl; inF.close(); return -2; } } inF.close(); cout<<"\nText data file read okey!\n"; return 0; } =============================== // Write binary data! #include <iostream> #include <fstream> using namespace std; // - - - - - - int main() { const int MaxN=8; fstream outF; double a[MaxN]; char *fname="data.dat"; int i; cout<<"Please input 8 double: "; for(i=0;i<MaxN;i++) cin>>a[i]; outF.open(fname,ios::out|ios::binary); if(!outF.is_open()) {cout<<"File open failed!\n"; return -1; } outF.exceptions(fstream::failbit| fstream::badbit); try{ outF.write((char *)a,MaxN*sizeof(double)); } catch(std::exception &e) {cout<<"Exception caught:"<<e.what()<<endl; outF.close(); return -2; } outF.close(); cout<<"Binary data file write okey!\n"; return 0; } ================================ // Read binary data! #include <iostream> #include <fstream> using namespace std; // - - - - - - int main() { fstream inF; double b; char *fname="data.dat"; cout<<"Please wait for reading data:\n"; inF.open(fname,ios::in|ios::binary); if(!inF.is_open()) {cout<<"File open failed!\n"; return -1; } inF.exceptions(fstream::failbit| fstream::badbit|fstream::eofbit); try{ while(1) { inF.read((char *)&b,sizeof(double)); cout<<b<<" "; } }catch(std::exception &e) { if(!inF.eof()) { cout<<"Exception caught:"<<e.what()<<endl; inF.close(); return -2; } } inF.close(); cout<<"\nBinary data file read okey!\n"; return 0; } ////////////////////////////////////////////////
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值