1, polymorphic
- Static polymorphic function overloading
- Polymorphic dynamic virtual functions inheritance
- Static binding address early binding, the compiler stage is an address
- Dynamic binding address late binding, runtime binding address
- Polymorphism -> parent class reference or pointer to the subclass object
- If the parent class with a pure virtual function, subclass inherits the parent class, it is necessary to implement a pure virtual function, and the parent class can not be instantiated objects. virtual int getResult () = 0; (abstract)
- Class virtual destructor virtual ~ name () {}
- To solve the problem: by the parent class pointer to a subclass object releases when problems caused by unclean.
- Virtual ~ destructor pure virtual class name = 0; the class declaration, the outer class implementation. Abstract class can not be instantiated.
- Type up conversion, down conversion type, polymorphic
2, function template
Type parameterization of Functional Programming - template technology
- template // tells the compiler to do the following if an error occurs T, T is a generic template, the template must be able to derive T, template <typename T>
template <class T>
void test(T &a, T &b)
{
T tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 10;
int b = 20;
//自动类型推导
test(a,b);
//显示指定类型
test<int>(a,b);
cout << "a = " << a << " ; b = " << b << endl;
- Normal function can be implicit type conversion, but not function templates.
- If overload occurs, the priority use ordinary function call, if not achieved, an error occurs.
- If you want to call the template function, you can use an empty parameter list print <> (a, b)
- Function template overloading can occur
- If the function templates can produce a better match ,, then the priority using a template function.
- limitation:
- Embodied by the custom data type, a function call from the solution defined data types.
template<> bool myComplate <Person>(Person &a, Person &b) { if (a.age == b.age) { return true; } return false; }
- Syntax: template <> return value of the function name <particular type> (parameter)
Class template
- wording template <T ...> followed class
- the difference function and the template, there may be a default type parameters, automatic type function template may be derived
template<class NameType, class AgeType>
class Person
{
public:
Person(NameType name, AgeType age = int )//类模板可以有默认的数据类型
{
this->age = age;
this->name = name;
}
NameType name;
AgeType age;
};
void test()
{
//自动类型推导
Person<string, int> p1("fsdf",20);
}
-
Member function does not create a start up, but created at runtime.
-
Explicitly specify the type of void dowork (Person <string, int> & p)
-
Parameter template of template <class T1, class T2>
-
Overall template of template <class T>
-
Class template inheritance
- If the base class is a template class, you must tell the compiler to make a subclass of the base class of T in the end is what type
- If you do not tell unable to allocate memory, the compiler does not pass
- Using the argument list class Child: public Base <int>
-
Class outside of class template member function
template < class T1, class T2> Person<T1, T2>::Person(T1 name, T2.age)
-
Recommended template documents do not write, you can write to, to declare and implement a class within a class, and finally the suffix to .hpp
-
Friend function within the class implementation
friend void print(Person<T1, T2>& p)
-
Friend function implemented outside the class
-
friend void print <> (Person <T1, T2> & p1); // No <> ordinary function declaration, plus <> template function declaration. Let the compiler sees a function, class and see the person
#include <iostream>
using namespace std;
#include <string>
template <class T1, class T2> class Person;
template <class T1, class T2> void print(Person<T1, T2>& p);
template <class T1, class T2>
class Person
{
friend void print<>(Person<T1, T2>& p);
public:
Person(T1 name, T2 age)
{
this->m_name = name;
this->m_age = age;
}
private:
T1 m_name;
T2 m_age;
};
template<class T1, class T2>
void print(Person<T1, T2>& p)
{
cout << "姓名: " << p.m_name << ";年龄: " << p.m_age << endl;
}
void test()
{
Person<string, int> p1("张三", 100);
print(p1);
}
int main()
{
test();
}
- Class template
3, type conversion
Static Transfer
- Based cast double d = static_case <double> (a)
- static <object type> (original object)
Dynamic conversion
- Base * base = dynamic_cast< base*>(child);
- Underlying type can not be converted, loss of accuracy, insecurity can be converted.
- Polymorphism may occur when the down-converted
Constant Conversion
- Is converted into constant pointer const pointer still point to the original object and
- Constant reference is converted to a const reference, and still point to the original object
4, abnormal
- Thrown throw in places may throw an exception
- If exceptions are not processed, the member function terminate the program interrupt.
try
{
myDevide(a,b);
}
catch(int) //捕获异常
{
cout << "异常" << endl;
}
catch(...) //捕获异常
{
cout << "异常" << endl;
}
Custom exception
class myException
{
public:
void printerror()
{
}
}
throw myException(); //抛出异常 匿名对象
catch(myException e) //捕获异常
{
e.printerror()
}
- Stack unwinding
- From the beginning try to throw before throwing an exception all objects on the stack is released.
Abnormal interface declaration: Use only in qt or linux, void func () throw (int) // int type can only throw exceptions, and throw () does not throw any type of exception
-
Abnormal life cycle
- MyException e, the cost will be more than one piece of data, call the copy constructor
- MyException * e, early release is not new objects, new delete their own management
- Recommended MyException & e, a data
-
Abnormal polymorphism using
- PrintError use polymorphism to achieve the same interface calls, throws a different error message.
-
Exception of using such systems to provide
- #include <stdexcept> include headers
- catch (out_of_range &e)
- cout << e.what();
The exception name Explanation logic_error logical error. runtime_error Run-time error. bad_alloc The use of new or new [] throws an exception when memory allocation fails. bad_typeid Typeid operation using a NULL pointer, and the pointer is a class with a virtual function, then bad_typeid thrown exception. bad_cast Use dynamic_cast conversion failed when thrown exception. ios_base::failure io An exception occurred during the. bad_exception This is a special exception, if the function's exception list declares bad_exception exception when internal function throws an exception list is no exception, if you call the unexpected () function throws an exception, regardless of what type, will be replace bad_exception type.
The exception name | Explanation |
---|---|
length_error | 试图生成一个超出该类型最大长度的对象时抛出该异常,例如 vector 的 resize 操作。 |
domain_error | 参数的值域错误,主要用在数学函数中,例如使用一个负值调用只能操作非负数的函数。 |
out_of_range | 超出有效范围。 |
invalid_argument | 参数不合适。在标准库中,当利用string对象构造 bitset 时,而 string 中的字符不是 0 或1 的时候,抛出该异常。 |
异常名称 | 说 明 |
---|---|
range_error | 计算结果超出了有意义的值域范围。 |
overflow_error | 算术计算上溢。 |
underflow_error | 算术计算下溢。 |
- 自己编写异常类
- string转char* 方法 this->info.c_str();
- 自己的异常类需要继承于 exception
- 重写 虚析构 和what()
- 内部维护一个错误信息字符串
- 构造时候传入错误信息字符串,what()返回
5、输入和输出流
- 标准输入流
cin.get()一次只能读一个参数
cin.get(一个参数)读一个字符
cin.get(两个参数)可以读字符串,读取字符串时不会拿走换行符”\n“
cin.getline()读取换行符并抛弃
cin.ignore() 没有参数忽略一个字符,带参数N,代表忽略n个字符
cin.peek() 偷窥,偷看一眼a,然后再放回数据缓冲区,缓冲区中还是a
cin.putback() 放回
案例:让用户输入指定范围的数字,如果不正确重新输入
- cin.fail() 标志位 0-> 正常 1-> 不正常
- cin.clear()重置标志位
- cin.sync()清空缓冲区
int num;
std::cout << "请输入一个1到10的数字:";
while (true)
{
std::cin >> num;
if (num > 0 && num <= 10)
{
std::cout << "你输入的数字为: " << num << std::endl;
}
std::cin.clear(); // 重置标志位
std::cin.sync(); //清空缓冲区
std::cout << "标志位: " << std::cin.fail << std::endl;
}
- 标准输出流
- cout.flush() 刷新缓冲区 Linux下有效
- cout.put() 向缓冲区写字符
- cout.write() 从buffer中写入num个字节到当前输出流中
- 格式化输出
- 通过流成员
int number = 99; cout.width(20); cout.fill(*); cout.setf(ios::left); 输出内容左对齐 cout.unsetf(ios::dec));卸载十进制 cout.setf(ios::hex); cout.setf(ios::showbase);强制输出整数基数 0 0x cout.unsetf(ios::hex) cout.setf(ios::oct);
- 控制符格式输出
#include <iomanip> int num = 2; cout << setw(20); << setfill('"') << setiosflags(ios::showbase) << setiosflags(ios::left) << hex << num << endl;
- File read and write
- Include headers #include <fstream>
- opstream ofs("./test.txt",ios::out | ios::trunc);
- Write data
//以输出的方式打开文件
ofstream ofs("./test.txt", ios::out | ios::trunc);
//后期指定打开方式
ofstream ofss;
ofss.open("./test.txt", ios::out | ios::trunc);
if (ofss.is_open())
{
cout << "打开成功" << endl;
}
ofs << "姓名: ";
- 读数据
```c
char buf[1024];
ifstream ifs("./test.txt", ios::in);
while (!ifs.eof()) //eof读到文件尾
{
ifs.getline(buf2, sizeof(buf2))
}
while (ifs >> buf) //按行读取
```