The essence of C and C ++ code: Reading Notes and Code Reading Notes
I recently read <C and C ++ code essence>, designed C ++ pointers, exception handling, and other aspects, some of which I think are very good code, it is worth learning from in the work.
1. pointer to a member function
A
#include<iostream>using namespace std;class C{ public:void f(){ cout<<"C::f\n";}void g(){cout<<"C::g\n";}};int main(){C c;void (C::*pmf)()=&C::f;(c.*pmf)();pmf=&C::g;(c.*pmf)();}
B
#include<iostream>using namespace std;class Object{public: void retrieve(){ cout<<"Object::retrieve"<<endl; } void insert(){ cout<<"Object::insert"<<endl; } void update(){ cout<<"Object::update"<<endl; } void process(int choice);private: typedef void (Object::*Omf)(); static Omf farray[3];};Object::Omf Object::farray[3]={&Object::retrieve,&Object::insert,&Object::update};void Object::process(int choice){ if(0<=choice && choice<=2) (this->*farray[choice])();}int show_menu(){ cout<<"1. retrieve\n"; cout<<"2. insert\n"; cout<<"3. update\n"; cout<<"4. quit\n"; cout<<"Please input a num\n"; int n; cin>>n; return n;}int main(){ int show_menu(); Object o; for(;;){ int choice=show_menu(); if(1<=choice && choice<=3) o.process(choice-1); else if(choice==4) break; } return 0;}
2. Implement your own assert macro
//assert.h#ifndef ASSERT_H#define ASSERT_Hextern void _assert(char*, char*, long);#define assert(cond) \((cond) \? (void) 0 \: _assert(#cond, __FILE__, __LINE__))#endif
Define your own _ assert method in the c file to conveniently use your own assert macro:
#include <stdio.h>#include <stdlib.h>#include "assert.h"void _assert(char* cond, char* fname, long lineno){fprintf(stderr, "Assertion failed: %s, file %s, line %ld\n", cond, fname, lineno);abort();}int main(){assert(3>4);return 0;}
3. Use setjmp to define a super redirect for Exception Handling
#include <stdio.h>#include <setjmp.h>jmp_buf jumper;void exception();int deal_exception();main(){ int value = 0; int i = 0; value = setjmp(jumper); if ( 0 == value ) { exception(); } else { switch ( value ) { case 1: printf( "solve exception[%d]\n",value ); break; case 2: printf( "solve exception[%d]\n",value ); break; case 3: printf( "solve exception[%d]\n",value ); break; default: printf( "solve exception[%d]\n",value ); break; } }}void exception(){ int _err_no = 3; if ( _err_no == 3 ) { printf("exception[%d]\n",_err_no); longjmp(jumper,_err_no); } return;}
4. Special Function Template
#include <iostream>#include <string.h>#include <string>using namespace std;template<class T>size_t bytes( T& t){cout<<"(using primary template)\n";return sizeof t;}size_t bytes( char*& t){cout<<"(using char* overload)\n";return sizeof t;}template<>size_t bytes<wchar_t*>( wchar_t*& t){cout<<"(using wchar_t* specialization)\n";return sizeof 2*(wcslen(t)+1);}template<>size_t bytes<>( string& s){cout<<"(using string explicit specialization)\n";return sizeof s;}template<>size_t bytes<float>( float& s){cout<<"(using float explicit specialization)\n";return sizeof s;}int main(){int i;cout<<"bytes in i:"<<bytes(i)<<endl;const char* s="Hello";cout<<"bytes in s:"<<bytes(s)<<endl;const wchar_t* w = (wchar_t*)"goodbye";cout<<"bytes in w:"<<bytes(w)<<endl;string t;cout<<"bytes in t:"<<bytes(t)<<endl;float f;cout<<"bytes in f:"<<bytes(f)<<endl;double d;cout<<"bytes in d:"<<bytes(d)<<endl;return 0;}
Class template Specialization
#include <iostream>using namespace std;template<class T, class U>class A{public:A(){cout<<"Primary template\n";}};template<class T, class U>class A<T*, U>{public:A(){cout <<"<T*,U> partial specialization\n";}};template<class T>class A<T, T>{public:A(){cout <<"<T,T> partial specialization\n";}};template<class U>class A<int, U>{public:A(){cout <<"<int,U> partial specialization\n";}};int main(){A<char,int> a1;A<char*,int> a2;A<float,float> a3;A<int, float> a4;return 0;}
5. How to change data members in constant member functions
A: this pointer is non-constant; B: mutable
#include <iostream>using namespace std;class B{public: B() {state =0;pos=0;} void f() const; void p() {cout<<"state= "<<state<<" pos= "<<pos<<endl;}private: int state; mutable int pos;};void B::f() const{ // ((B*)this)->state=1; const_cast<B*>(this)->state=1; pos = 1;}int main(){ B b; b.p(); b.f(); b.p(); return 0;}
6. Signal
#include <stdio.h>#include <signal.h>void ctrlc_handler(int sig);volatile sig_atomic_t ccount = 0;int main(){char buf[100];if(signal(SIGINT, ctrlc_handler) == SIG_ERR){fputs("Error installing ctrlc handler\n", stderr);}while(gets(buf)){puts(buf);}signal(SIGINT, SIG_DFL);printf("You pressed ctrlc %d times\n", ccount);return 0;}void ctrlc_handler(int sig){signal(sig, ctrlc_handler);++ccount;return;}
7. Exception Handling: resource allocation is the initialization Principle
/*exception:logic_errordomain_errorinvalid_argumentlength_errorout_of_rangeruntime_errorrange_erroroverflow_errorunderflow_errorbad_allocbad_castbad_exceptionbad_typeid*/#include <cstdio>#include <memory>using namespace std;class File{ FILE* f;public: File(const char* fname, const char* mode) { f = fopen(fname,mode); if(!f) throw 1; } ~File() { if(f) { fclose(f); puts("File closed"); } }};int main(){ void f(const char*); try { //f("file0.txt"); f("file1.txt"); } catch(int x) { printf("Caught exception:%d\n", x); } return 0;}void f(const char* fname){ auto_ptr<File> xp(new File(fname,"r")); puts("Processing file..."); throw 2;}
8. Non-standard template library container
#include <valarray>#include <iostream>#include <algorithm>//#include <boost/foreach.hpp>using namespace std;void print(double i){ cout << i <<" ";}int main(){const int N = 10;const double values[N] = {0,1,2,3,4,5,6,7,8,9};const valarray<double> v1(values,N);//for_each(&values[0], &values[9], ptr_fun(print));/*BOOST_FOREACH(double d, values){cout<< d << endl;} */for_each(&v1[0], &v1[10], ptr_fun(print));cout<<endl;cout << "min: "<<v1.min()<<endl;cout << "max: "<<v1.max()<<endl;cout << "sum: "<<v1.sum()<<endl;return 0;}
9 handle memory allocation exceptions
A try {} catch (const bad_alloc & x)
B set_new_handler
#include <iostream>#include <stdlib.h>using namespace std;inline void my_handler(){cout << "Memory exhausted" <<endl;abort();}int main(){set_new_handler(my_handler);for(int i=0;;++i){(void) new double[100];if((i+1) % 10 == 0)cout << (i+1) << " allocations" <<endl;}return 0;}
10. Never run 9 On your computer!