首页 > 代码库 > C和C++代码精粹读书笔记

C和C++代码精粹读书笔记

最近看了<<C和C++代码精粹>>, 设计到C++的指针,异常处理等方方面面,其中有些自认为非常不错的代码,在工作中非常值得借鉴。


1.指向成员函数的指针

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.实现自己的assert宏

//assert.h
#ifndef ASSERT_H
#define ASSERT_H


extern void _assert(char*, char*, long);
#define assert(cond) ((cond) 	? (void) 0 	: _assert(#cond, __FILE__, __LINE__))
#endif

在c文件中定义自己的_assert方法,就可以方便的使用自己的assert宏了:

#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.使用setjmp定义超级转向来进行异常处理

#include <stdio.h>
#include <setjmp.h>

jmp_buf jumper;
void exception();
int  deal_exception();

main()
{
     int value = http://www.mamicode.com/0;>4. 函数模板特化

#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;

}
类模板特化

#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.常量成员函数中改变数据成员的方法
A :this 指针去常量性;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. 信号
#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:
	logic_error
		domain_error
		invalid_argument
		length_error
		out_of_range
	runtime_error
		range_error
		overflow_error
		underflow_error
	bad_alloc
	bad_cast
	bad_exception
	bad_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. 非标准模板库容器

#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 处理内存分配异常

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!

C和C++代码精粹读书笔记