类的组合
一个类内嵌其他类的对象作为成员的情况
has - a组合
初始化列表的另一用途:为了调用数据成员的带参构造函数
能够层层递进
class Line
{
public:
Line(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0);
Line(const Line &other);
~Line();
Line(const Point &p1, const Point &p2);
void showLine(void);
private:
Point m_p1, m_p2;
};
Line::Line(int x1, int y1, int x2, int y2) : m_p1(x1, y1), m_p2(x2, y2)
{
}
Line::Line(const Line &other) : m_p1(other.m_p1), m_p2(other.m_p2)
{
}
Line::~Line()
{
}
Line::Line(const Point &p1, const Point &p2) : m_p1(p1), m_p2(p2)
{
}
void Line::showLine()
{
m_p1.showPoint();
cout << "->";
m_p2.showPoint();
cout << endl;
}
Line l1(1, 2, 3, 4);
Line l2(l1);
Point p1(5, 6);
Point p2(7, 8);
Line l3(p1, p2);
l1.showLine();
l2.showLine();
l3.showLine();
前向引用声明
针对引用和指针
class A; //前向声明
class B
{
public:
void fn(A *a){} //或者 void fn(A &a){}
};
class A
{
public:
void fn(B *b){} //或者 void fn(B &b){}
};
作用域
全局作用域 — 名称前面加两个冒号
匿名作用域(相当于c中的static) — 直接使用
作用域的关系
全局命名空间作用域,要访问时加上::
例::x
作用域可见性的一般规则如下:
1、标识符要声明在前,引用在后
2、在同一作用域中,不能声明同名的标识符
3、在没有互相包含关系的不同的作用域中声明的同名标识符,互不影响
4、如果在两个或多个具有包含关系的作用域中声明了同名标识符,则外层标识符在内层不可见
生存期
静态生存期:对象的生存期与程序的运行期相同
全局变量(全局对象)
static修饰的静态局部变量:调用时创建,程序结束之后销毁
动态生存期:诞生于声明点,作用域结束时会被销毁
匿名对象生存期:
匿名对象:函数返回值为一个对象时,调用函数返回的对象就是匿名对象
为动态生存期,若是对匿名对象加名字(加常引用),匿名对象生存期将会被改变
const Clock &ref = Clock(11, 22, 33);
左值和右值
locatiable left value:能被取地址就是左值
readable right value:不能被取地址就是右值
所有的匿名对象都是右值而非左值
右值引用:希望能够使用匿名对象,起一个右值引用类型的别名
(给匿名对象起名字)
例:Clock &&ref = Clock(11, 22, 33);
类的静态成员
静态属性不为本类对象所特有的,而为本类所有对象所共有的属性
数据类型 类名 ::成员名
即类中的对象为声明,实际的对象是全局变量
静态对象函数:不需要使用对象.函数来调用,可以直接类名::函数来使用
静态数据成员:具有唯一性,对象有几个都没关系,这个成员在内存中只有一份
静态成员函数:不需要对象出现就能调用
在类的静态成员中不能访问类的非静态成员
在类的非静态成员中既可以访问类的非静态数据成员也可以访问类的静态数据成员
单例模式
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton *creat()//creat在没有对象的时候也能调用(类名::函数)
{
if (m_p == NULL)
{
m_p = new Singleton;//new:在堆上申请一个空间
}
return m_p;
}
static void destory()
{
delete m_p;//相当于free
m_p = NULL;
}
private:
Singleton() {}
static Singleton *m_p;//使得对象只能创建一个
};
Singleton *Singleton::m_p = NULL;
int main()
{
Singleton *p, *q;
p = Singleton::creat();
q = Singleton::creat();//虽然分两次调用,但是调用的都是同一个东西,称为单例调用
cout << p << endl;
cout << q << endl;
Singleton::destory();//类的使用者使用完之后调用销毁程序
return 0;
}
使用counter验证是否为单例模式
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton *creat()//creat在没有对象的时候也能调用(类名::函数)
{
if (m_p == NULL)
{
m_p = new Singleton;//new:在堆上申请一个空间
}
return m_p;
}
static void destory()
{
delete m_p;//相当于free
m_p = NULL;
}
static int getcounter()
{
return counter;
}
~Singleton()
{
--counter;
}
private:
Singleton()
{
++counter;
}
static Singleton *m_p;//使得对象只能创建一个
static int counter;
};
Singleton *Singleton::m_p = NULL;
int Singleton::counter = 0;
int main()
{
Singleton *p, *q;
cout << Singleton::getcounter() << endl;
p = Singleton::creat();
q = Singleton::creat();//虽然分两次调用,但是调用的都是同一个东西,称为单例调用
cout << Singleton::getcounter() << endl;
cout << p << endl;
cout << q << endl;
Singleton::destory();//类的使用者使用完之后调用销毁程序
cout << Singleton::getcounter() << endl;
return 0;
}
类的友元函数 / 类
临时打破类的访问权限设置,从而在类外对类内的私有成员访问的机制