资源描述
封装 继承 多态
1. 封装,数据部分,class name
2. 继承, 在实现程序时,可以像生活中儿子继承父母遗产一样,子类将父类中的属性(类中的数据成员)和行为(类中的成员函数) 继承,从而实现父类所有内容为子类所用的功能(代码重用)
3. 多态, 在实现程序时,可以将父类的行为(类中的成员函数)再次定义从而实现新的行为(重载,重写),使程序的执行结果多样化
其实类的话和结构体的字节大小算法不一样,不管它的大小
Public(本类,子类,其他类) --- 》 protected(本类,子类) --- 》 private(本类)。
Private私有的 只能在一个地方(本类)访问。
类的初始化
1. 在类里面,必须创建对象之后才能初始化,不能在类里面直接初始化。一般数据类型不能在类外面初始化,但是静态的(static)类型可以再类的外面进行初始化--(有且只有static在类外可以初始化,因为静态的是在全局数据区存放的,在编译的时候就给它分配内存了)。
2. 类里面的数据可以是任意的,但是不能有本类的对象(因为不知道怎么分配内存),本类的指针是可以的,
3. 静态函数当中不能出现this,this是在运行的时候才有。
构造函数
1. 构造函数的作用就是对类里面的数据进行初始化
2. 构造函数是自动调用
3. 构造函数不能写返回值,
4. 最好写一个自己的默认构造函数以防止出现错误。
Malloc只能分配堆内存,new不仅能分配内存调用有参数的构造函数,对类的数据进行初始化。
构造函数可以用(初始化列表)
student():count(0);
student(char *name,Int age,int c):count(c);
对常量count进行初始化。
引用也必须在初始化列表当中进行初始化。
初始化列表的顺序是按照定义的顺序,并且是包含的小类先执行,它比构造函数还先执行。
当类内有成员为指针的时候,不能简单的复制,要把堆内存分配,然后再把值拷过来,
析构函数()
为了避免内存泄露用到析构函数,析构顺序与构造函数的顺序正好相反!
迭代器
String-----str.reserve(20),只改变容量str.capacity
String-----str.resize(30),改变实际的字节数str.size,str.length,当然还有str.capacity
1. Str.append连接,
2. str.assign拷贝,
3. str.at(0)修改第一个字符,
4. str.empty()判断是空返回1;
5. pare()比较字符串(相等返回0)
6. str.substr(0,5)截取字符串;
7. str.swap(str2)交换;
8. str.find;查找str.find_first_of;---str.find_first_not_of;
9. str.replace(0,5,”hello”);
10. str.insert();字符串插入
string迭代器
相当于指针
返回一个对象的时候,调用拷贝函数
静态数据成员
不管有多少个对象,静态数据成员只有一个内存,它会随着对象的改变而直接改变;(可以用它来记录有多少个对象)
**1.静态成员函数不能调用非静态成员函数,但是可以调用静态成员函数(因为静态成员函数是在编译的时候分配内存,一般函数是在运行的时候才分配内存).静态只能访问静态的!
**2.一般函数可以调用静态函数.
嵌套类(外部类 内部类)
内部类不可以访问外部类的一般数据,只能访问静态数据,但是外部类可以访问内部类的任何类型数据(这是由于内部类和外部类是两个类,编译的时候先编译内部类再编译外部类的).
局部类
局部类里面不能有静态的数据成员和静态的成员函数;
友元
友元啊,在定义类里面给函数前面加上friend即可,
可以将一个类定义为另一个类的友元类……
指向类中数据成员的指针,注意声明的时候要加类域,初始化也要注意,(int student::*p;
P = &student::age
Stu.*p = 10)
例子如下:
#include <iostream>
#include <string>
using namespace std;
class student
{
public:
int age;
student(){}
int fun(int age)
{
this->age = age;
return this->age;
}
};
int main()
{
student stu;
int student::*p;
p = &student::age;
stu.*p=10;
cout<<stu.*p<<endl;
int (student::*pfun)(int);
pfun = &student::fun;
int result = (stu.*pfun)(20);
cout<<result<<endl;
}
继承
父类的私有部分不能被继承,
先按照继承的顺序执行调用构造函数,
例如:
#include <iostream>
#include <string>
using namespace std;
class A
{
public:
A(int){cout<<"A construct"<<endl;}
};
class B
{
public:
B(int){cout<<"B construct"<<endl;}
};
class C
{
public:
C(){cout<<"C construct"<<endl;}
};
class D:public C,public A,public B
{
public:
B b;
C c;
A a;
D(int i,int j,int k):A(i),B(j),a(i),b(j)
{
cout<<"D construct"<<endl;
}
};
int main()
{
D d(1,2,3);
}
执行的顺序应该是C A B B C A D;(1.按照继承顺序 2.先构造父类对象再构造子类对象,)
C++允许多继承,当子类继承多个的时候是按照继承的顺序,1.子类公有继承父类的函数 原来公有的在子类里面还是公有的,原来是保护的在子类里面还是保护的,私有数据不能被继承,所以总是保存原有父类的访问权限。
2.子类保护继承父类的函数 原来父类的公有的在子类里面变成保护的,私有数据不能被继承,原有保护的在子类里面还是保护的,
3.子类私有继承父类的函数 都是私有的了
虚函数
要把父类的析构函数定义为虚函数(virtual),让程序实现动态联编,防止父类指针指向子类的时候,不调用析构函数会造成一定的内存泄露;父类指针可以指向子类对象,但是子类指针不能指向父类对象。静态联编(在编译时根据指针类型确定函数的调用)根据类型,动态联编(在运行的时候确定函数的调用)根据指针指向的对象。 虚函数表
纯虚函数 virtual void fun() = 0;(在本类中只有纯虚函数的声明,没有具体实现) 抽象类(有纯虚函数的类)不能够创建对象,可以声明指针, 只能作为基类使用.
纯虚析构函数必须在本类当中实现,必须在本类当中定义,
一般纯虚函数都是由子类去实现,
Bool operator == (形参) 定义该函数进行比较
bool operator ==(const student &stu) const
{
if(this->pare(stu.stuid) == 0)
{
return true;
}
else
return false;
}
If(stu1 == stu2)
通过操作符重载可以直接拿两个对象进行比较
模板
template <typename T1,typename T2>
class student
{
public:
T1 age;
T2 name;
student(){}
student(T1 age,T2 name)
{
this->age = age;
this->name = name;
}
void show();
};
template <typename T1,typename T2>
void student<T1,T2> ::show()
{
cout<<this->age<<" "<<this->name<<endl;
}
int main()
{
student<int,string>stu(19,"zhangsan");
stu.show();
}
容器
for_each(vec.begin(),vec.end(),showint);
插入:
vec.insert(vec.begin(),9);
删除注意:
vec.pop_back();//删除最后一个
// vec.erase(vec.begin()+3,vec.end()-2);
// vec.erase(vec.end());//删除所有
vec.clear();//删除所有
修改:
Vec.at(1) = 200;
查找:
Find(vec.begin(),vec.end(),”xiaoqiao”);
bool operator()(const string& str)
{
if(str.substr(5,3).compare("ing") == 0)
return true;
else
return false;
}
其中str.substr(5,3).compare(“ing”)中 5代表从第五个开始找,3代表找3个字符,ing是要查找的字符。
排序:
sort(vec3.begin(),vec3.end(),cmpstu);
统计字符个数:
count(vec.begin(),vec.end(),"hhhh"); 表示统计有几个“hhhh”的个数!
交换:
Vec.swap(vec2);
Vector, deque(双端队列), queue(队列), stack(堆),list;
其中queue的que.size()会自增,
Lis.remove(“mengde”);删除
Lis.splice(lis.end(),lis2);(拼接---剪切lis2的数据连接到lis后面去)
三种拼接方式如下:
lis.splice(lis.end(),lis2);
lis.splice(lis.begin(),lis2,++lis2.begin());
lis.splice(lis.begin(),lis2,++lis2.begin(),lis2.end());
去除重复值:
Lis.unique();注意去出重复之前最好先排序lis.sort(),可以把重复的其中一个删除;
倒序 : lis.reverse();
赋值: lis.assign(++lis2.begin(),--lis2.end());//赋值
lis.assign(3,"fuck");//赋值 两种方式都会覆盖掉原来的数据
set:自动排序,不允许插入相同的数据;
set<int,less<int> > set2; 按照由小到大的,默认也是这样的
set<int,greater<int> > set2; 由大到小自动排序。
查找:
set<int> set1;
set1.insert(1);
set1.insert(7);
set1.insert(3);
set1.insert(8);
// for_each(set1.begin(),set1.end(),showint);
pair<set<int>::iterator,set<int>::iterator >pr;
// pr = set1.equal_range(8); -----8 ,4
// pr = set1.equal_range(4); -----7,7
// pr = set1.equal_range(0); -----1, 1
pr = set1.equal_range(20); -----4,4
cout<<*(pr.first)<<" "<<*(pr.second)<<endl;
查找:
set<int> set1;
set1.insert(1);
set1.insert(4);
set1.insert(7);
set1.insert(11);
set<int>::iterator it;
// it = set1.lower_bound(15);
it = set1.upper_bound(15);
cout<<*it<<endl
map插入:
map.insert(2,200);--à其中2是键,200是值
可以允许值相同但是不能允许键相同,否则插不进去,
map<int,int> m1;//
typedef pair<int,int> INT_pair;
m1.insert(INT_pair(1,100));
m1.insert(INT_pair(3,300));
m1.insert(INT_pair(4,900));
m1.insert(INT_pair(2,200));
pair<map<int,int>::iterator,bool> pr;
pr = m1.insert(INT_pair(4,400));
if(pr.second == true)
cout<<"insert OK "<<(*(pr.first)).first<<" "\
<<(*(pr.first)).second<<endl;
else
cout<<"insert faild!"<<endl;
map删除:
// m1.erase(++m1.begin());
// m1.erase(--m1.end());
// m1.erase(2);
m1.erase(m1.begin(),m1.end());
map查找修改:
map<int,int>::iterator it;
it = m1.find(2);
if(it != m1.end())
{
cout<<"find and update "<<it->first<<" "<<it->second<<endl;
it->second = 999;
}
else
cout<<"faild"<<endl;
当然还可以直接用键查找
cout<<"3 "<<m1.at(3)<<endl;
cout<<"m1[1]: "<<m1[1]<<endl;
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
vec.push_back(5);
vec.push_back(6);
// random_shuffle(vec.begin(),vec.end());随机排序
replace(vec.begin(),vec.end(),4,999);把4用999来替换
r everse(vec.begin(),vec.end()); 倒置
merge(vec.begin(),vec.end(),vec2.begin(),vec2.end(),vec3.begin()); 把vec和vec2的数据连接放在vec3里面(必须先用vec3.resize()为它分配空间);
for_each(vec.begin(),vec.end(),showint);
通用算法都不能改变容器的容量。
异常处理
int main()
{
cout<<"start main"<<endl;
try
{
cout<<"start try"<<endl;
throw 1;
cout<<"end stry"<<endl;
}
#if 1
catch(int)
{
cout<<"int exception"<<endl;
}
#endif
cout<<"main over"<<endl;
}
文件:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
// ofstream out("hello"); 创建文件
// char *buffer = "fuck yourself"; 把字符串写入到buffer里面
// out<<buffer; 写入文件
// out.flush(); 刷入
// out.close(); 关闭
ifstream in("hello");
char buffer[128];
#if 1
while(in.getline(buffer,sizeof(buffer)-1) != NULL)
cout<<buffer<<endl;
#endif
#if 0
string str;
while(getline(in,str) != NULL)
cout<<str<<endl;
#endif
}
还可以这读取
string filename = "hello";
ifstream in(filename.c_str());
string str;
while(getline(in,str) != NULL)
cout<<str<<endl;
除
除
除
除
除
展开阅读全文