Type Alias
和typedef类似,甚至可以说作用一模一样,都是给类型起别名,Type Alias需要借助关键字using。有三种使用场景:
场景1:给函数指针起别名
using func=void(*)(int,int);
......
void example(int a,int b){}
func fun=example;
场景2:为模板参数起别名
template<typeneme T>
class Container{
using velue_type=T;
};
......
template<typename Container>
void fun(const Container& c)
{
typename Container::value_type n;
}
这种方式再C++标准库中非常常见,容器、迭代器、仿函数中大量使用。
场景3:为模板类型起别名
即Alias Template(化名模板),用以隐藏模板参数,简化书写。
template<typename Char>
using mystring=std::basic_string<Char,std::char_traits<Char>>;
......
mystring<char> str;
在标准库中有typedef basic_string string.
拓展
using的几种使用形式: 1、命名空间的使用指令
using namespace std;
2、命名空间成员的使用声明
using std::cout;
3、类成员的使用声明
class HH {
protected:
int hh;
};
class XX:public HH {
protected:
using HH::hh;
public:
void test() {
hh = 1;
}
};
4、C++2.0以后有Type Alias和Alias Template使用using关键字
noexcept
异常(exception)是一门大学问,值得程序员认真研究。
void fun()noexcept;
void swap(Type& a,Type& b)noexcept(noexcept(a.swap(b)))
{
a.swap(b);
}
异常若在本函数中被抛出后没有被处理,就会向上传递异常到调用该函数的函数中,等待处理,若还是没有被处理,就再向上传递,直到没有函数调用关系为止。 若直到最后异常都没有被处理,程序会触发调用std::terminate(),而在std::terminate()中会调用std::abort()终止程序。 注意:移动构造函数和移动赋值函数一般声明为noexcept,这两者往往只意味着内存所有权的转让,而不涉及内存的分配,因此一般不会有异常。使用noexcept声明一方面有助于程序员推断程序逻辑,另一方面编译器可以更好地优化代码。
class MyString{
private:
char* _data;
size_t _len;
...
public:
MyString(MyString&& str)noexcept:_data(str._data),_len(str._len){...}
MyString& operator=(MyString&& str)noexcept{
...
return *this;
}
};
override
override用于修饰子类重写的父类的虚函数,用于显示告诉编译器所修饰的函数为重写父类的虚函数,防止出现笔误造成实质上重新在子类中定义了一个函数。
class Base{
public:
virtual void func(int a){}
};
class Derived:public Base{
public:
void fun(int a){};
void func(int a){};
};
final
用于修饰有继承体系的类,以及类中的虚函数。 **用于修饰类:**表明 该类(被final修饰)是继承体系中最下层的类,不会再有其他类去继承该类
class Base1 {};
class Base2 final :public Base1 {};
class Base3:public Base2{};
用于修饰虚函数:表明所有继承自 该虚函数(被final修饰)所在类的类,不再有权利重写该虚函数
class Base1 {
public:
virtual void fun(){}
};
class Base2:public Base1 {
public:
virtual void fun()final{}
};
class Base3:public Base2{
public:
virtual void fun(){}
};
|