大家都说C++难学,我也正在学习,之所以难是可能因为没有了解C++中的一些很基础的东西,有点似懂非懂的感觉,而没有真正了解C++的运行机制,我一直在学习基础,这篇博客源于一个简单的类,这就是我所知道的一个简单类,博客中的观点大部分来至Effective C++和More Effective C++两本书,我是反复看了好几遍,还会一直看,因为我的C++还很菜。
一个简单的类源码:
#include <iostream> usingnamespacestd; classUInt { public: //缺省构造函数,在没有任何构造函数的时候,编译器默认生成缺省构造函数 UInt(){}
//这个构造函数可以把int类型隐式转换成UInt类型 //两种函数允许编译器进行类型转换:但参数构造函数和隐式类型转换运算符 UInt(constint& i):val(i) { cout<<"int"<<endl; }
//拷贝构造函数 UInt(constUInt& i):val(i.val){ cout<<"UInt"<<endl; }
//析构函数 ~UInt(){ cout<<"~UInt"<<endl; }
//赋值运算符 UInt&operator=(constUInt& i) { cout<<"operator="<<endl; val=i.val; return*this; }
//其他的类型可以赋值给UInt类型,当然该报错的还是得报错(如你传入一个string类型),总比秘密做了很多 你不想要的好吧 template<typename T> UInt&operator=(constT& i) { cout<<"operator = other"<<endl; val=i; return*this; }
//取址运算符 UInt*operator&() { returnthis; }
//返回类型是一个常量指针,也就是说接收这个方法返回值的变量必须为常量指针 //这是一个常量方法,所以不能修改成员变量的值 constUInt*operator&()const { returnthis; }
//返回当前对象的引用,当然你就可以对他进行任何合法的操作 //返回类型为引用类型或者指针类型就不会有临时变量的构造和析构 UInt&operator++() { *this+=1;//this是一个指针类型,*this为值类型,运算符左侧必须为值类型 return*this;//引用类型是对实际数据的引用,只能把值类型赋给引用类型,当然指针类型是不能 赋给引用类型的 }
//返回的是一个局部变量,你对局部变量的任何操作都是没有意义的,所以返回类型为const //大家都知道局部变量在超出他的作用域之后会自动析构,现在却返回一个局部变量,这里其实产生了一个临时 变量,用oldVal初始化临时变量, //若没有变量接收当前方法的返回值,方法调用完成之后,临时变量会自动析构, //若有变量接收当前方法的返回值,临时变量在该变量自动析构之前析构,在栈中先定义后析构,这就是传说中的 先进后出! constUIntoperator++(int) { UInt oldVal(*this); ++(*this); returnoldVal; }
//加法运算,产生了一个局部变量uint,在函数返回时还会产生一个临时变量,程序要负责两个UInt类型的构造 和析构,所以说+=比+效率高 constUIntoperator+(constUInt i) { UIntuint(*this); uint.val+=i.val; returnuint; }
//UInt类型可以和char、short、int、float、double等类型进行加减乘除运算 template<typename T> constUIntoperator+(T t) { UIntuint(*this); uint.val+=t; returnuint; }
//返回当前对象,你可以对他进行任何合法的操作,所以他的类型为non-const UInt&operator+=(constUInt& i) { val+=i.val; return*this; }
//UInt类型可以和其他基本类型(能和int类型进行+=运算的所有类型)进行+=运算 template<typename T> UInt&operator+=(constT& i) { val+=i; return*this; }
//乘法 不是指针 constUIntoperator*(constUInt& i) { cout<<"operator*"<<endl; UIntuint(*this); uint.val=uint.val*i.val; returnuint; }
template<typename T> UIntoperator*(constT& i) { cout<<"operator* other"<<endl; UIntuint(*this); uint.val=uint.val*i; returnuint; }
//乘法 不是指针 UInt&operator*=(constUInt& i) { val*=i.val; return*this; }
template<typename T> UInt&operator*=(constT& i) { val*=i; return*this; }
//隐式类型转换,将UInt类型转换成int类型,当出现类型不匹配的时候,编译器会寻找可能进行匹配的 类型转换,有时候这个隐式的类型转换可能不是你要的 //如UInt类型与int类型进行混合运算时,UInt类型会自动转换成int类型 operatorint()const { returnval; }
private: intval; }; |