扩展运算符的作用
比如:我自定义了一个类Animal
Animal a;
Animal b;
Animal c=a+b
cout<
返回值类型 operator+(形参列表) //表示我想对+进行运算符重载
{
}
注意:“operator+”你可以理解为就是个函数的名字
①把运算符重载作为类的成员函数
规定:左值是函数调用者, 右值函数的参数
class Dog
{
//对加法进行运算符重载 是Dog的成员函数
Dog operator+(Dog &otherdog)
{
函数体;
}
};
②把运算符重载作为类的友元函数(注意写法的差异,不能使用this,不属于类的成员函数)
规定:左值为第一个参数, 右值为第二个参数
class Dog
{
friend Dog operator+(Dog &dog1,Dog &dog2);
};
//定义一个普通函数去重载加法运算
Dog operator+(Dog &dog1,Dog &dog2)
{
函数体;
}
单目运算符重载 a++ ++a a-- --a ~a !a
后置++ operator++(int)
前置++ operator++()
双目运算符重载 + - * / % > < !=
①重载运算符不能改变运算符原本的语义
②不能发明新的运算符号
③不能重载
.(成员访问运算符)
.*(成员指针访问运算符)
::(域运算符)
sizeof(数据类型长度运算符)
?:(条件运算符, 三目运算符)
STL: standard template library(标准模板库)
里面提供了大量的模板类,可以划分为如下几种
用来存放大量数据的
向量vector: 连续存储的元素
assign() //重复使用会覆盖vector前面存放的数据
at(i) //获取对应下标的元素 myvector[i]
insert() //在指定迭代器位置插入数据
pop_back() //删除最后一个元素
push_back() //尾插
列表list:由节点组成的双向链表,每个结点包含着一个元素
merge() 合并两个链表
集合set:由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序
emplace(); //往set中存放数据
find(); //查找指定元素并返回迭代器
映射map: 由{键,值}对组成的集合,以某种作用于键对上的谓词排列
例如:
键 | 值 |
---|---|
星期一 | monday |
星期二 | tuesday |
星期三 | wensday |
栈stack:后进先出的值的排列
队列queue:先进先出的执的排列
封装算法用来使用
通俗地理解为就是一个指针,专门指向容器中的某个数据
C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:
TYPE b = (TYPE)a
C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。
static_cast 静态类型转换。如int转换成char
reinterpreter_cast 重新解释类型
dynamic_cast 命名上理解是动态类型转换。如子类和父类之间的多态类型转换。
const_cast, 字面上理解就是去const属性。
4种类型转换的格式:
TYPE B = static_cast<TYPE> (a)
静态类型转换,编译的时c++编译器会做类型检查;
基本类型能转换 但是不能转换指针类型
若不同类型之间,进行强制类型转换,用reinterpret_cast<>() 进行重新解释
结论:
①C语言中能隐式类型转换的,在c++中可用 static_cast<>()进行类型转换。因C++编译器在编译检查一般都能通过;
②C语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强行类型解释。
总结:static_cast<>()和reinterpret_cast<>() 基本上把C语言中的 强制类型转换给覆盖
很难保证移植性。
动态类型转换,安全的基类和子类之间转换;运行时类型检查
去除变量的只读属性
int main(void)
{
double dPi = 3.1415926;
//1静态的类型转换: 在编译的时 进行基本类型的转换 能替代c风格的类型转换 可以进行一部分检查
int num1 = static_cast<int> (dPi); //c++的新式的类型转换运算符
int num2 = (int)dPi; //c语言的 旧式类型转换
int num3 = dPi; //隐士类型转换
cout << "num1:" << num1 << " num2:" << num2 << " num3:" << num3 << endl;
char *p1 = "hello world" ;
int *p2 = NULL;
p2 = (int *)p1;
//2 基本类型能转换 但是不能转换指针类型
//p2 = static_cast (p1); //“static_cast”: 无法从“char *”转换为“int *”
//3 可以使用 reinterpret_cast 进行重新解释
p2 = reinterpret_cast<int *> (p1);
cout << "p1 " << p1 << endl;
cout << "p2 " << p2 << endl;
//4结论:
//c语言中能隐式类型转换的 在c++中可以用 static_cast<>()进行类型转换 //C++编译器在编译检查一般都能通过
//c语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强行类型 解释
return 0;
}
class Animal{
public:
virtual void cry() = 0;
};
class Dog : public Animal{
public:
virtual void cry(){
cout << "wangwang " << endl;
}
void doSwim() {
cout << "我要狗爬" << endl;
}
};
class Cat : public Animal{
public:
virtual void cry(){
cout << "miaomiao " << endl;
}
void doTree() {
cout << "我要爬树" << endl;
}
};
class Book{
public:
void printP(){
cout << price << endl;
}
private:
int price;
};
void ObjPlay(Animal *base){
base->cry();
Dog *pDog = dynamic_cast<Dog *>(base);
if (pDog != NULL){
pDog->cry();
pDog->doSwim();
}
Cat *pCat = dynamic_cast<Cat *>(base);
if (pCat != NULL){
pCat->cry();
pCat->doTree();
}
}
int main(void){
Animal *base = NULL;
//1 可以把子类指针赋给 父类指针 但是反过来是不可以的需要如下转换
//pdog = base;
Dog *pDog = static_cast<Dog *> (base);
//2 把base转换成其他非动物相关的 err
//Book *book= static_cast (base);
//3 reinterpret_cast //可以强制类型转换
Book *book2= reinterpret_cast<Book *> (base);
//4 dynamic_cast用法
ObjPlay(new Cat());
return 0;
}
①若有异常则通过throw操作创建一个异常对象并抛掷。
② 将可能抛出异常的程序段嵌在try块之中。控制通过正常的顺序执行到达try语句,然后执行try块内的保护段。
③ 如果在保护段执行期间没有引起异常,那么跟在try块后的catch子句就不执行。程序从try块后跟随的最后一个catch子句后面的语句继续执行下去。
④ catch子句按其在try块后出现的顺序被检查。匹配的catch子句将捕获并处理异常(或继续抛掷异常)。
⑤ 如果匹配的处理器未找到,则运行函数terminate将被自动调用,其缺省功能是调用abort终止程序。
⑥处理不了的异常,可以在catch的最后一个分支,使用throw语法,向上扔。
例子
int divide(int x, int y )
{
if (y ==0)
{
throw x;
}
return x/y;
}
int main(void)
{
try
{
cout << "8/2 = " << divide(8, 2) << endl;
cout << "10/0 =" << divide(10, 0) << endl;
}
catch (int e)
{
cout << "e" << " is divided by zero!" << endl;
}
catch(...)
{
cout << "未知异常" << endl;
}
cout << "ok" << endl;
return 0;
}