类型转换
C语言中的强制类型转换是不推荐的,因为任何类型都能强制转换,这就可能导致出现很多问题,所以c++提供了四个关键字来进行类型转换。
- static_cast<T>(expr)
——用于基本类型间的转换,但不能用于基本类型指针间的转换
——用于有继承关系类对象之间的转换和类指针间的转换
- reinterpret_cast<T>(expr)
——用于指针类型之间的强制转换
——用于整数和指针类型间的强制转换
- const_cast<T>(expr)
——用于去除变量的 const 属性
- dynamic_cast<T>(expr)
——主要用于类层次间的转换,还可以用于类之间的交叉转换
#include <iostream>
using namespace std;
class A
{
public:
virtual void show()
{ }
};class B : public A
{
public:
virtual void show()
{ }
};int main()
{
A a;
B b;
A *pa = &a;
B *pb = &b;
//pa = &b; //父类指针指向子类对象
pa = dynamic_cast<A *>(&b); //必须具备多态属性
pb = dynamic_cast<B *>(&a); //可以转换,但是有问题
return 0;
}
异常
什么是异常
1)异常是一种程序控制机制,与函数机制独立和互补
函数是一种以栈结构展开的上下函数衔接的程序控制系统,异常是另一种控制结构,它依附于栈结构,却可以同时设置多个异常类型作为网捕条件,从而以类型匹配在栈机制中跳跃回馈.
2)异常设计目的:
栈机制是一种高度节律性控制机制,面向对象编程却要求对象之间有方向、有目的的控制传动,从一开始,异常就是冲着改变程序控制结构,以适应面向对象程序更有效地工作这个主题,而不是仅为了进行错误处理。
异常设计出来之后,却发现在错误处理方面获得了最大的好处。
异常的基本语法
栈解旋
异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上的构造的所有对象,都会被自动析构。析构的顺序与构造的顺序相反。这一过程称为栈的解旋(unwinding)。
异常接口声明
int Div(int x, int y); //异常函数声明,可以抛出任何异常
int Div(int x, int y) throw(); //不能抛出任何异常
int Div(int x, int y) throw(int, char); //可以抛出int和char型异常void func() throw (A, B, C , D); //这个函数func()能够且只能抛出类型A B C D及其子类型的异常。
异常类型
1)throw的异常是有类型的,可以使,数字、字符串、类对象。
2)throw的异常是有类型的,catch严格按照类型进行匹配。
异常的层次结构
//类的异常
#include <iostream>
using namespace std;
class MyArray
{
private:
int m_len;
int *m_data;
public:
MyArray(int l);
~MyArray();
int &operator [](int index)
{
return m_data[index];
}
int GetLength()
{
return m_len;
}
class eSize
{
protected:
const char *ErrMsg;
public:
eSize(char *msg) : ErrMsg(msg)
{}
virtual void printErr() = 0;
};
class eNegative : public eSize
{
public:
eNegative() : eSize("Negative exception")
{}
void printErr()
{
cout << ErrMsg << endl;
}
};
class eZero : public eSize
{
public:
eZero() : eSize("Zero exception")
{}
void printErr()
{
cout << ErrMsg << endl;
}
};
class eTooSmall : public eSize
{
public:
eTooSmall() : eSize("TooSmall exception")
{}
void printErr()
{
cout << ErrMsg << endl;
}
};
class eTooBig : public eSize
{
public:
eTooBig() : eSize("TooBig exception")
{}
void printErr()
{
cout << ErrMsg << endl;
}
};
};
MyArray::MyArray(int l)
{
m_len = l;
if(m_len < 0)
{
throw eNegative();
}
else if(m_len == 0)
{
throw eZero();
}
else if(m_len > 0 && m_len <= 10)
{
throw eTooSmall();
}
else if(m_len > 1000)
{
throw eTooBig();
}
m_data = new int[m_len];
}
MyArray::~MyArray()
{
if(m_data != NULL)
{
delete[] m_data;
}
}
int main()
{
try
{
MyArray a(20);
for (int i = 0; i < a.GetLength(); i++)
{
a[i] = i;
}
}
catch(MyArray::eNegative &e)
{
e.printErr();
}
catch(MyArray::eZero &e)
{
e.printErr();
}
catch(MyArray::eTooSmall &e)
{
e.printErr();
}
catch(MyArray::eTooBig &e)
{
e.printErr();
}
return 0;
}
c++输入输出流
程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件。
C++输入输出包含以下三个方面的内容:
对系统指定的标准设备的输入和输出。即从键盘输入数据,输出到显示器屏幕。这种输入输出称为标准的输入输出,简称标准I/O。
以外存磁盘文件为对象进行输入和输出,即从磁盘文件输入数据,数据输出到磁盘文件。以外存文件为对象的输入输出称为文件的输入输出,简称文件I/O。
对内存中指定的空间进行输入和输出。通常指定一个字符数组作为存储空间(实际上可以利用该空间存储任何信息)。这种输入和输出称为字符串输入输出,简称串I/O。
常用的输入输出流头文件
- iostream 包含了对输入输出流进行操作所需的基本信息。
- fstream 用于用户管理的文件的I/O操作。
- strstream 用于字符串流I/O。
- stdiostream 用于混合使用C和C + +的I/O机制时,例如想将C程序转变为C++程序。
- iomanip 在使用格式化I/O时应包含此头文件。
标准 I / O 流
标准I/O对象:cin,cout,cerr,clog
标准输入流对象cin,重点掌握的函数
cin.get() //一次只能读取一个字符 遇到EOF结束
cin.get(一个参数) //读一个字符
cin.get(三个参数) //可以读字符串
cin.getline()
cin.ignore()
cin.peek()
cin.putback()
标准输出流对象cout
cout.flush()
cout.put()
cout.write()
cout.width()
cout.fill()
cout.setf(标记)
manipulator(操作符、控制符)
flush
endl
oct
dec
hex
setbase
setw
setfill
setprecision
文件I/O
和文件有关系的输入输出类主要在fstream.h这个头文件中被定义,在这个头文件中主要被定义了三个类,由这三个类控制对文件的各种输入输出操 作,他们分别是ifstream、ofstream、fstream,其中fstream类是由iostream类派生而来
文件的读写
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream ofs("world.txt", ios::app);
char buf[32] = {0};
ifstream ifs("hello.txt", ios::in);
ifs >> buf;
ofs << buf;
return 0;
}