本期是C++基础语法分享的第六节,今天给大家来分享一下:
(1)引用;
(2)宏;
(3)成员初始化列表;
(4)封装;
(5)继承;
(6)多态;
引用
左值引用
常规引用,一般表示对象的身份。
右值引用
右值引用就是必须绑定到右值(一个临时对象、将要销毁的对象)的引用,一般表示对象的值。
右值引用可实现转移语义(Move Sementics)和精确传递(Perfect Forwarding),它的主要目的有两个方面:
消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。
能够更简洁明确地定义泛型函数。
引用折叠
X& &、X& &&、X&& & 可折叠成 X&
X&& && 可折叠成 X&&
宏
宏定义可以实现类似于函数的功能,但是它终归不是函数,而宏定义中括弧中的“参数”也不是真的参数,在宏展开的时候对 “参数” 进行的是一对一的替换。
成员初始化列表
好处
更高效:少了一次调用默认构造函数的过程。
有些场合必须要用初始化列表:
常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化
initializer_list 列表初始化
用花括号初始化器列表初始化一个对象,其中对应构造函数接受一个 std::initializer_list 参数。
initializer_list 使用
#include 《iostream》#include 《vector》#include 《initializer_list》 template 《class T》struct S { std::vector《T》 v; S(std::initializer_list《T》 l) : v(l) { std::cout 《《 “constructed with a ” 《《 l.size() 《《 “-element list
”; } void append(std::initializer_list《T》 l) { v.insert(v.end(), l.begin(), l.end()); } std::pair《const T*, std::size_t》 c_arr() const { return {&v[0], v.size()}; // 在 return 语句中复制列表初始化 // 这不使用 std::initializer_list }}; template 《typename T》void templated_fn(T) {} int main(){ S《int》 s = {1, 2, 3, 4, 5}; // 复制初始化 s.append({6, 7, 8}); // 函数调用中的列表初始化 std::cout 《《 “The vector size is now ” 《《 s.c_arr().second 《《 “ ints:
”; for (auto n : s.v) std::cout 《《 n 《《 ‘ ’; std::cout 《《 ‘
’; std::cout 《《 “Range-for over brace-init-list:
”; for (int x : {-1, -2, -3}) // auto 的规则令此带范围 for 工作 std::cout 《《 x 《《 ‘ ’; std::cout 《《 ‘
’; auto al = {10, 11, 12}; // auto 的特殊规则 std::cout 《《 “The list bound to auto has size() = ” 《《 al.size() 《《 ‘
’; // templated_fn({1, 2, 3}); // 编译错误!“ {1, 2, 3} ”不是表达式, // 它无类型,故 T 无法推导 templated_fn《std::initializer_list《int》》({1, 2, 3}); // OK templated_fn《std::vector《int》》({1, 2, 3}); // 也 OK}
面向对象
面向对象程序设计(Object-oriented programming,OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。
面向对象三大特征 —— 封装、继承、多态
封装
把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。关键字:public, protected, private。不写默认为 private。
public 成员:可以被任意实体访问
protected 成员:只允许被子类及本类的成员函数访问
private 成员:只允许被本类的成员函数、友元类或友元函数访问
继承
基类(父类)——》 派生类(子类)
多态
多态,即多种状态(形态)。简单来说,我们可以将多态定义为消息以多种形式显示的能力。
多态是以封装和继承为基础的。
C++ 多态分类及实现:
重载多态(Ad-hoc Polymorphism,编译期):函数重载、运算符重载
子类型多态(Subtype Polymorphism,运行期):虚函数
参数多态性(Parametric Polymorphism,编译期):类模板、函数模板
强制多态(Coercion Polymorphism,编译期/运行期):基本类型转换、自定义类型转换
静态多态(编译期/早绑定)
函数重载
class A{public: void do(int a); void do(int a, int b);};
动态多态(运行期期/晚绑定)
虚函数:用 virtual 修饰成员函数,使其成为虚函数
动态绑定:当使用基类的引用或指针调用一个虚函数时将发生动态绑定
注意:
可以将派生类的对象赋值给基类的指针或引用,反之不可
普通函数(非类成员函数)不能是虚函数
静态函数(static)不能是虚函数
构造函数不能是虚函数(因为在调用构造函数时,虚表指针并没有在对象的内存空间中,必须要构造函数调用完成后才会形成虚表指针)
内联函数不能是表现多态性时的虚函数
动态多态使用
class Shape // 形状类{public: virtual double calcArea(){ 。.. } virtual ~Shape();};class Circle : public Shape // 圆形类{public: virtual double calcArea(); 。..};class Rect : public Shape // 矩形类{public: virtual double calcArea(); 。..};int main(){ Shape * shape1 = new Circle(4.0); Shape * shape2 = new Rect(5.0, 6.0); shape1-》calcArea(); // 调用圆形类里面的方法 shape2-》calcArea(); // 调用矩形类里面的方法 delete shape1; shape1 = nullptr; delete shape2; shape2 = nullptr; return 0;}
责任编辑:haq
-
封装
+关注
关注
126文章
7873浏览量
142893 -
C++
+关注
关注
22文章
2108浏览量
73619
原文标题:C++基础语法梳理:引用、封装、继承和多态
文章出处:【微信号:cyuyanxuexi,微信公众号:C语言编程学习基地】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论