- 1.头文件与类的声明
- 2.构造函数
- 3.参数传递与返回值
- 4.操作符重载与临时对象
- 5.主要代码
1.头文件与类的声明
c语言中,data和函数都是分别定义,根据类型创建的。这样创建出的变量,是全局的,会有很大影响。
cpp中,将数据data和处理数据的函数都包含在一起(class),创建出一个对象,即为面向对象。数据和函数(类的方法)都是局部的,不是全局的。
class的两个经典分类:无指针成员的类(complex,复数)、有指针成员的类(string)。
如果include过了,就不要在声明了。防卫式声明,如果没定义这个名词,那么就定义一下。ifndef+define。(这样如果程序是第一次引用它,则定义,后续则不需要重复定义,不需要重复进入下面的过程)
1是要写的类的声明,
2是要写类的具体定义,
写12的时候发现有一些东西需要提前声明,写在0处。
模板类型,这里用符号T表示。
这里的意思是,因为实部和虚部的类型不确定,可能是double、float、int,定义起来比较费劲。我自己定义一个模板类型叫做T来满足这个要求。
将T作为一个类型参数来传入,在调用的时候就可以指定类型了。
通过在定义类的前面加入一行代码template来实现。
1.定义类的时候,可以直接在body中定义函数(inline函数,在body中定义完成),也可以只是在body中声明函数。
2.inline内联函数。如果定义的函数是内联函数,那么会比较好,运行比较快,尽可能定义为内联函数。
3.在body外,通过inline关键字来指定该函数为inline函数。
4.注意的是,上面所有的inline函数,都只是我们指定的,希望它为inline,具体是不是,要看编译器来决定。
数据应该被定为private,这样外界看不到。函数应该定义为public,被外界使用。
1.通过构造函数来创建对象。会自动调用构造函数进行创建。
2.构造函数名称需要与类的名称一样。函数的参数可以有默认参数。构造函数没有返回类型。
3.注意,不要使用赋值的方法来写构造函数,使用构造函数的特殊的方法来写,更规范。使用初值列、初始值。
1.构造函数可以有很多个,可以重载。但是上面的12两个构造函数冲突了,右面的调用方式对两个构造函数都适用,冲突。
2.同名的函数可以有多个,编译器会编成不同的名称,实际调用哪个会根据哪个适用。
1.通常构造函数不要放在private中,这样外界没法调用,也就无法创建对象。
在设计模式Singleton(单体)中,将构造函数放在了private中。这个class只有一份,外界想要调用的时候,只能使用定义的2.getinstance函数来取得这一份;外界无法创建新的对象。
1.定义函数的时候,函数名后面➕const,对于不会改变数据内容的函数,一定要加上const。
2.对于上面右侧调用方式,我们创建一个常量复数然后输出实部虚部,**如果上面real和img函数定义的时候,没有加const,那么这里函数默认的意思是可能会改变数据,与我们的常量复数就矛盾了。**编译器会报错。因此,对于不会改变数据内容的函数,一定一定要加const。
1.参数传递,传递value是把整个参数全传过去,double4字节。尽量不要直接value传递。
2.尽可能传递引用reference,传引用相当于传指针,很快,形式又很漂亮。
3.传引用过去,修改之后,都会改变;如果只是为了提升速度,不向改变数据,那么传const引用。这样传进去的东西,不能被修改。
1.返回值的传递,也尽量返回引用。
2.1中操作符重载的声明中,没有写变量名,也可以写上。c++中,声明函数的时候,可以不写变量名,实现的时候必须写。
1.友元:friend,修饰在函数定义之前,表示这个函数可以直接拿该类对象的private数据。
2.如上面所示,声明为friend之后,函数可以直接取到re和im,如果不被声明为friend,只能通过调用real和imag函数来得到,效率较低。
相同class的不同对象objects互为友元,即可以直接拿到另一个object的data。
1.第一种方式,写成成员函数。所有的成员函数都带有一个隐藏的参数this(是一个指针),this表示(指向)调用这个函数的调用者。
2.定义函数的时候,在参数列中不能写出来this,直接用即可。
1.传递者无需知道接受者是以引用形式接受。
2.这里面虽然返回值需要的是引用,但是代码中写的返回值可以是value。
3.+=操作符中,定义的参数是引用,但是传进去的c1也可以是value。
4.接收端使用什么形式接收与传递者无关。
5.上面的操作符,进行操作之后,c2改变了,返回了c2的引用。因此感觉上,将操作符写为void函数也可以,但实际上,为了可以兼容c3+=c2+=c1的形式,写成返回引用更好。
1.非成员函数的操作符重载。(没有this)
2.应对客户的三种方法,写出三种方式,使用时进行重载。
3.非成员函数是local函数。
4.这些函数不能返回引用,必须是一个local object。因为这里面的操作符中二者不是一个加到另一个上,是两个对象相加,因此返回必须是一个对象,不是引用。
5.typename(),创建一个typename类型的临时对象。
complex.h complex_text.cpp
operator <<要构造成非成员函数,因为c1<#ifndef __MYCOMPLEX__
#define __MYCOMPLEX__
class complex;
complex&
__doapl(complex* ths, const complex& r);
class complex
{
public:
complex(double r = 0, double i = 0) :re(r), im(i) { }
complex& operator += (const complex&);
double real() const { return re; }
double imag() const { return im; }
private:
double re, im;
friend complex& __doapl(complex*, const complex&);
};
//友元
inline complex&
__doapl(complex* ths, const complex& r)
{
ths->re += r.re;
ths->im += r.im;
return *ths;
}
//成员函数
inline complex&
complex::operator +=(const complex& r)
{
return __doapl(this, r);
}
inline double
real(const complex& x)
{
return x.real();
}
inline double
imag(const complex& x)
{
return x.imag();
}
inline complex
operator +(const complex& x, const complex& y)
{
return complex(real(x) + real(y), imag(x)+imag(y));
}
inline complex
operator +(const complex& x)
{
return x;
}
inline complex
operator -(const complex& x)
{
return complex(-real(x),-imag(x));
}
inline bool
operator == (const complex& x, double y)
{
return real(x) == y && imag(x) == 0;
}
#include
#include



