xia复习
上一天的学习内容:
重点:1、封装———— 就是对类的抽象 ,将一种对象的共性 抽象成一个类。
2、三个函数——-构造函数/复制构造函数/析构函数
注意:析构函数和构造函数的调用顺序刚好相反。
新内容
两个类的关系
1、 has-a //
类的组合 ,描述的就是一个类内嵌其他类的对象作为成员的情况,他们之间的关系是一种包含和被包含的关系。
eg: //在线类中内嵌两个点的对象
class Point
{
public:
Point(int x=0, int y=0);
Point(const Point &other):m_x(other.m_x),m_y(other.m_y)
{
cout<<"&Point" <<endl;
}
~Point()
{
cout<<"~Point" <<endl;
}
void setX(int x);
void setY(int y);
int getX();
int getY();
void show();
private:
int m_x, m_y;
};
Point::Point(int x, int y):m_x(x),m_y(y)
{
cout<<"Point(int )" <<endl;
}
void Point::setX(int x)
{
m_x = x;
}
void Point::setY(int y)
{
m_y = y;
}
void Point::show()
{
cout<< m_x<<","<< m_y <<endl;
}
int Point::getX()
{
return m_x;
}
int Point::getY()
{
return m_y;
}
class Line
{
public:
Line(int x1,int y1,int x2,int y2):m_p1(x1,y1),m_p2(x2,y2)
{
cout<< "Line (int int int int )"<< endl;
}
Line(const Point &p1,const Point &p2):m_p1(p1),m_p2(p2)
{
cout<< "Line (const Point &p1,&p2)"<< endl;
}
~Line()
{
cout<< "~Line"<< endl;
}
void show()
{
m_p1.show();
cout << "->"<< endl;
m_p2.show();
}
private:
Point m_p1,m_p2;
};
2、 is-a //
类的继承关系。
前向引用声明
class A;
class B
{
public:
A *a;
void fn(A &a)
{
}
}
class A
{
public:
B *b;
}
若是不在classB之前声明A B中的A对象的定义会报错。
而且这里在类中定义的不能是对象,需要是指针。或者是一个引用的值,不能是对象。
注意:在编程在多文件时注意尽量在源文件中包头文件,不在头文件中包头文件。
UML类图
示例如上
标识符作用域与可见性的问题
C++的比C语言扩展了一些问题:
1、类的作用域
类内访问,类外访问
2、命名空间作用域:
namespace 命名空间
namespace CD
{
class Clock
{
};
void foo()
{
}
}
namespace XA
{
class Clock
{
};
}
int main(void)
{
CD::Clock c;
}
这个时候创建的c 就是CD 命名空间的c 。
using CD::Clock; //先声明CD中的Clock 这个函数 后面使用的时候 默认是CD命名空间的
后面使用的时候可以直接写函数或者类;
using namespace CD;
CD中所有的内容都不需要加”::“去访问。
匿名命名空间:
namespace
{
class Clock
{
}
}
这个匿名命名空间的类和操作只能在本文件中使用。
(类似于C语言中全局变量前的static)
全局命名空间作用域
全局空间的标识符(函数)在使用时候加上两个::就是全局命名空间作用域的函数
void read()
{
::read(fd,p,10); //这里的read就不是他自己而是全局命名空间作用域的read
}
作用域和作用域之间是可以互相包含的
1、标识符要声明在前,引用灾后
2、在同一作用域中,不能声明同名标识符
3、在没有相互包含关系的不同作用域中同名标识符互不相影响。
4、如果两个或多个具有包含关系的作用域,外层不可见
静态 : 生存期与程序运行周期相同 ----> static 全局变量
动态 :
static修饰之后 只会被创建一次 不会重复创建 并且结束时间为程序结束的时候。
若是加了static的静态变量 没有初始化 那它默认为 0;
匿名对象可以通过&来进行起别名
const Clock &ref = Clcok(10,20,30);
但此时的ref不能.showtime(); 只能读不能写。
&&ref 右值引用
lvalue locatable
如果可以取地址 就是左值
rvalue
如果不能取地址 就是右值
所有的匿名对象都是右值
右值向左值的转换
&&i= 10;
i = 100;
此时输出就是100;
C++的循环:
int a[] = {1,2,3,4,5,6,7,8,9,0};
int len = sizeof(a) / sizeof(a[0]);
for(int x: a) //base range for
{
cout << x << endl ;
}
for(int i = 0; i < len ; ++i)
{
cout<< a[i] <<endl ;
}
他们两个输出结果相同。
单例模式:
23种设计模式其中之一 比较简单的 不适用虚函数的
单例模式:
一个类的类对象只能创建一个出来 这个类的对象只能有一个
这就是单例模式。
class SingelTon
{
public:
static SingelTon * getIntance()
{
if(m_p == NULL)
{
m_p = new SingelTon;
}
return m_p;
}
static void destroyIntance()
{
delete m_p;
m_p = NULL;
}
static int getCounter()
{
return counter;
}
private:
SingelTon()
{
counter++;
}
~SingelTon()
{
counter--;
}
static SingelTon *m_p;
static int counter;
};
SingelTon* SingelTon::m_p = NULL;
int SingelTon::counter;
SingelTon *p;
p = SingelTon::getIntance();
SingelTon *q;
cout << SingelTon::getCounter() << endl;
q = SingelTon::getIntance();
cout << SingelTon::getCounter()<< endl;
cout << p << endl;
cout << q << endl;
SingelTon::destroyIntance();
cout << SingelTon::getCounter()<< endl;
输出结果:
1
1
0x1c02280
0x1c02280
0
this指针
c1.showtime();
调用类中的函数时 其实函数传入了参数 &c1。
间接传了个参数 这个指针是 this 指针
类的静态成员函数中不存在this指针!
常数据成员 必须进行初始化
常引用之后 必须按照常量 去使用了
const int i 在定义的时候必须要初始化。在类中也要用初始化列表进行初始化const常量
注意:C++中不能通过指针来修改变量
强制类型转换
四个是用来进行强转的关键字。
或者 const_cast <int * >(& i) //这个就是把 const int* 强转成int *