C++基础语法梳理:引用封装继承和多态

Posted 一起学编程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++基础语法梳理:引用封装继承和多态相关的知识,希望对你有一定的参考价值。

本期是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\\n";
    }
    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:\\n";
 
    for (auto n : s.v)
        std::cout << n << ' ';
    std::cout << '\\n';
 
    std::cout << "Range-for over brace-init-list: \\n";
 
    for (int x : {-1, -2, -3}) // auto 的规则令此带范围 for 工作
        std::cout << x << ' ';
    std::cout << '\\n';
 
    auto al = {10, 11, 12};   // auto 的特殊规则
 
    std::cout << "The list bound to auto has size() = " << al.size() << '\\n';
 
//    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;
}

今天的分享就到这里了,大家要好好学C++哟~

写在最后:对于准备学习C/C++编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!

C语言C++编程学习交流圈子,QQ群:904329806点击进入】微信公众号:C语言编程学习基地

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

编程学习书籍分享:

 编程学习视频分享:

以上是关于C++基础语法梳理:引用封装继承和多态的主要内容,如果未能解决你的问题,请参考以下文章

C++基础语法多态

C++基础语法多态

C++的三大特性封装继承和多态

JS面向对象基础篇(封装 继承 多态)

Java基础——面向对象三大特征(继承封装多态)

Java10-java语法基础——java的封装性