1.类和对象
1.1类的相关实现
第一种方法是将类的成员函数定义在类体内,这里不再介绍
第二种方法是将类体内的成员函数的实现放在类体外,此时需要域运算符“::”,和第一种效果一样。
class apple
{
public:
//数据成员
int index;
//成员函数
int getindex();
};
//类成员函数实现部分
int apple::getindex()
{
return index;
}
C++语言一般在头文件放入函数的声明,在cpp文件里面放入函数的实现,同样可以在头文件里面放入类的定义,将类的成员函数实现在实现文件内,存放类的头文件和实现文件最好和类的名称相同。例如:
//apple.h文件
#include<stdio.h>
#include....
class apple
{
public:
int index;
int getindex();
}
...
//apple.cpp文件
#include<apple.h>
...
int apple::getindex()
{
return index;
}
...
1.2构造函数
#include<iostream>
class apple
{
public:
apple();
apple(int iindex,short isize);
int index;
short size;
...
}
//默认构造函数初始化
apple::apple()
{
index=1;
size=2;
}
//在带参数的构造函数中初始化
apple::apple(int iindex,short isize)
{
index=iindex;
size=iisize;
}
int apple::getindex()
{
return index;
}
...
void main()
{
apple a1;
cout<<a1.getindex()<<endl; //输出1
apple a2(10,20);
cout<<a1.getindex()<<endl; //输出10
}
1.3类成员
如果在类定义的时候没有加任何关键字,默认状态成员都在private区域。
1.3.1静态类成员
若将类成员定义为静态类成员,则允许使用类名直接访问,大概是因为叫这个名字的只有一个大家的值都一样吧,用类直接访问不用担心混淆,静态类成员是在类成员定义前使用static关键字标识。在定义静态数据成员时,通常需要在类体外对静态数据成员初始化。例如:
class apple
{
public:
static unsigned int price; //定义一个静态数据成员
}
unsigned int apple::price=10; //初始化静态数据成员
...
int main(...)
{
apple a1;
cout<<apple::price<<endl; //通过类名访问静态成员
cout<<a1.price<<endl; //通过对象访问静态成员
}
在定义类的数据成员时,可以为成员函数指定默认参数,其参数默认值可以是类的静态数据成员,但是普通数据成员则不能作为函数默认参数。
另外静态成员函数只能访问静态数据成员
在定义静态数据成员函数时,如果函数的实现代码处于类体之外,则在函数的实现部分不能在标static关键字。
class apple
{
public:
static unsigned int price;
int abc;
void output(int data =price) //以静态数据作为默认参数
{
cout<<data<<endl;
}
void out(int data=abc) //错误,普通成员不能作为默认参数
{
...
}
static void outt()
{
cout<<price<<endl; //正确的访问
cout<<abc<<endl; //错误的访问,不能访问非静态
}
...
} ;
static void apple::outt(); //错误的定义
关于嵌套类和友元相关需要的时候再补充。
2.继承与派生
2.1类的继承
继承有3种派生方式,public,protected,private,”:”表示基类和派生类之间的继承关系,例如:
class phone
{
public:
int size;
char name[10];
};
class iphone:public phone
{
public :
char version[10];
int sizes;
}
注意:私有成员不能被继承,在派生时若子类中定义了一个与父类同名的成员函数,此时子类会隐藏父类的成员函数
2.2继承后的可访问性
公有型派生后基类该什么型还什么样,privated的还是不能访问
保护型派生后原来的public和protected成员在派生类中均为protected,只是在派生类定义的时候可以访问,用派生类定义的对象不能访问,在类体外也不能访问,也就是说,protected成员可以被基类所有派生类使用,就是不能更改。
私有型派生基类中的private还是不能访问。
2.3构造函数访问顺序
从父类派生一个子类并声明一个子类对象时,它将先调用父类的构造函数,然后调用当前类的构造函数来创建对象,在释放对象的时候,先调用的是当前类的析构函数,最后是父类的析构函数。
无论调用的是那种子类的构造函数,都会先调用父类默认的构造函数,若想用父类带参数的构造函数则需要显示调用。例如:
#include....
...
class father
{
public:
int ID;
char name [10];
father(char name[10])
{
strcpy(char name[]);
}
father()
{
strcpy(name,"HH");
}
...
};
class son:public father
{
public:
char smallname[10];
son(char name[]):father(name)
{
cout<<.....<<endl;
}
};
int main(...)
{
son jack("jack");
}
3.STL标准库模板
标准模板库,即STL,是根据本地C++标准规范定义的一套强大的函数模板类模块库。它主要包含容易,算法,函数对象。
3.1结合容器
结合容器主要通过关键码提高查询和操作的效率。一般包括set,multiset,map…
以下几个例子
3.1.1multiset类模板
multiset是程序能顺序存储一类数据,与集合类相似,多重集合的元素既可以作为存储的数据,又可以作为数据的关键字,于集合类不同的是可以包含重复的数据。
multiset<int> imul;
imul.insert(1);
imul.insert(2);
...
multiset<int>::iterator it; //定义相关迭代器
for(it=imul.begin();it!=imul.end();it++)
cout<<*it<<endl;
int target=1;
it=imul.find(target);
if(it==imul.end())
cout<<"not found"<<endl;
else
cout<<"founded"<<endl;
其他容器类似,不再赘述,后面主要介绍算法。
3.2算法
算法是STL中枢,STL提供了算法库,算法库中都是模板函数,迭代器主要负责从容器中获取一个对象,算法与具体对象在容器的什么位置等细节无关。
标准算法分四个类别:非修正序列算法,修正序列算法,排序算法,数值算法。
3.2.1非修正序列算法
非修正序列算法不修改他们所作用的容器,例如计算个数或者查找元素的函数,STL提供的主要非修正序列算法(常用)如下:
count(first,last,val) //计数
equal(first,last,first2) //判断相等
find(first,last,val) //搜索
for_each(first,last,func) //对范围内的元素进行func操作
下面举个简单的例子:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void Output(int val)
{
cout << val << ' ';
}
void main()
{
vector<char> charVect;
charVect.push_back('M');
charVect.push_back('L');
charVect.push_back('A');
charVect.push_back('G');
charVect.push_back('v');
charVect.push_back('U');
for_each(charVect.begin(), charVect.end(), Output);
cout << endl;
sort(charVect.begin(), charVect.end());
for_each(charVect.begin(), charVect.end(), Output);
int cnt=count(charVect.begin(),charVect.end(),5);
cout<<cnt<<endl;
system("pause");
}
3.2.2修正序列算法
修正序列算法有些操作会改变容器的内容,例如复制或者指定填充,只列出主要的算法,不再举例。
copy(first,last,first2); //复制
copy_backward(first,last,first2); //逆向复制
random_shuffle(first,last); //随机重排
swap(it1,it2); //置换
replace(first,last,val1,val2); //取代某种元素
fill(first,last,val); //改填元素值
3.2.3排序算法
排序算法的特点是对容器的内容进行不同方式的排序,常用算法如下:。
max(val1,val2); //最大值
min_elemnent(first,last); //最小值所在位置
sort(first,last); //升序排序
partial_sort(first,middle,last);//局部排序
下面举个简单的例子:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void Output(int val)
{
cout << val << ' ';
}
void main()
{
vector<char> charVect;
charVect.push_back('M');
charVect.push_back('L');
charVect.push_back('A');
charVect.push_back('G');
charVect.push_back('v');
charVect.push_back('U');
for_each(charVect.begin(), charVect.end(), Output);
cout << endl;
part_sort(charVect.begin(), charVect.begin()+3,charVect.end());
for_each(charVect.begin(), charVect.end(), Output);
//对迭代器first到last范围内元素进行排序,把排序后的前一部分元素放到序列前一部分first-mid,其余部分放在后一部分mid-last。
system("pause");
}
3.3迭代器
迭代器相当于指向容器的元素的指针,他在容器内可以各种移动,有输入,输出,和随机操作的迭代器,下面细说。
3.3.1输出迭代器
输出迭代器只用于写一个序列,它可以进行递增和提取操作
#include<iostream>
#include<vector>
using namespace std;
void main(){
vector<int> intVect;
for(int i=0;i<10;i+=2)
intVect.push_back(i);
cout<<endl;
vector<int>::iterator it=intVect.begin();
while(it!=intVect.end())
cout<<*it++<<endl;
}
3.3.2输入迭代器
输入迭代器只用于读一个序列,它可以进行递增,提取,比较操作
#include<iostream>
#include<vector>
using namespace std;
void main(){
vector<int> intVect(5);
vector<int>::iterator out=intVect.begin();
*out++=1;
*out++=3;
*out++=5;
*out++=7;
*out=9;
cout<<endl;
vector<int>::iterator it=intVect.begin();
while(it!=intVect.end())
cout<<*it++<<endl;
}
3.3.3随机访问迭代器
随机访问迭代器最强大,不仅具有双向迭代器的所有功能,还能使用指针的算术运算和比较运算。
#include<iostream>
#include<vector>
using namespace std;
void main(){
vector<int> intVect(5);
vector<int>::iterator it=intVect.begin();
*it++=1;
*it++=3;
*it++=5;
*it++=7;
*it=9;
cout<<endl;
for(it=intVect.begin();it!=intVect.end();it++)
vout<<*it<<endl;
it=intVect.begin();
*(it+2)=100; //此时输出第三个元素已经变为100;
while(it!=intVect.end())
cout<<*it++<<endl;
}