zoukankan      html  css  js  c++  java
  • C++系列:对象和类(一)

    背景

    面向对象编程

    首先,面向对象编程(Object-Oriented Programming, OOP)是一种编程风格/程序设计思想/编程范式。它强调以对象(数据+方法)为中心,而不是以过程为中心(即面向过程编程)。

    由此可见,从某种意义上讲,编程语言可以在不同程度上支持这种风格。即使 C 语言也可以实现这种风格,只不过实现起来难度更大、更为曲折。

    C++ 就是对 OOP 特性支持的比较好的编程语言。

    抽象

    抽象(abstraction)是一种 OOP 特性。处理复杂问题的方法之一就是提供简单的抽象。那么,抽象究竟表示什么意思?

    这里的抽象表示去除无关信息或隐藏细节信息,以减少问题复杂度的过程

    一个典型的例子是:对于老司机开车这件事,我们只需要关心速度、油量等指标(数据表示);以及启动、换挡、踩油门、刹车、转方向盘、开闪光灯等操作过程(数据操作)。我们不需要知道发动机究竟怎么启动的,电路和管路是怎么布局的等问题。

    因此,这里使用抽象的一个关键就是:尝试从用户的角度去考虑对象的构建,先去定义用户和对象的交互(即接口),再去想对象的内部数据和接口实现。

    封装

    封装(encapsulation)是一种 OOP 特性。封装有多种含义,OOP 中的封装的语义是:将数据表示和数据操作,绑定到一个对象中,不能直接访问对象的数据,只能通过方法来访问或修改对象的数据。

    C++ 中的类(class)就是一种提供抽象的方式,它也相当于自定义类型

    定义类需要确定两个部分:一种称为类声明;一种称为类方法定义

    类声明用于声明数据成员和成员函数(类的蓝图,常常放在头文件),类方法定义用于定义成员函数(类的细节,常常放在库文件)。

    类声明部分  

    C++ 提供了访问控制关键字:public 和 private。这两个关键字可以限定对象中数据和方法的访问权限,private 提供了数据隐藏,进而加强了类的封装特性。

    由于这只是声明,所以一般情况下,普通的成员函数只需要提供函数头。但是也有例外,有些成员函数可以直接提供函数定义,这种成员函数会隐式地定义为内联函数,又叫内联方法。内联函数一般用于短小的函数,编译器会进行优化,避免函数调用的栈开销,例如下面示例中的 SetGrade。

    示例如下:

     1 // student.h
     2 #pragma once
     3 #include <iostream>
     4 #include <string>
     5 
     6 class Student
     7 {
     8 public:
     9     void InitializeData(const std::string& name, int score);
    10     void SetGrade(int val) { grade = val; };
    11     void ShowGrade();
    12 
    13 private:
    14     int grade;
    15     std::string name;
    16 };

    这 Student 类的声明,放在头文件。它声明了类的数据成员成员函数,但是没有给出普通成员函数(即非内联的)的定义。

    从类的设计上来看,声明部分把数据成员放在了私有部分,而把成员函数放在了公有部分。公有部分构成了公共接口,而私有部分提供了数据隐藏

    类方法定义部分

    在类方法定义部分,使用 :: 来为成员函数指定类名,它的术语叫作用域解析运算符(scope-resolution operator)

    类方法定义部分提供了实现细节。

     1 // student.cpp
     2 #include "student.h"
     3 
     4 void Student::InitializeData(const std::string& name_val, int grade_val)
     5 {
     6     name = name_val;
     7     grade = grade_val;
     8 }
     9 
    10 void Student::ShowGrade()
    11 {
    12     using namespace std;
    13     cout << name << " has grade of " << grade << "." << endl;
    14 }

    我们看到,成员函数可以访问私有数据成员(name 和 grade)。

    类的简单使用

    student.h 和 student.cpp 构成了 Student 类的完整定义,接下来是 Student 类的简单使用。

     1 // main.cpp
     2 #include "student.h"
     3 
     4 int main()
     5 {
     6     Student s1;
     7     Student s2;
     8     s1.InitializeData("zhangsan", 80);
     9     s2.InitializeData("lisi", 59);
    10     s1.ShowGrade();
    11     s2.ShowGrade();
    12     s1.SetGrade(99);
    13     s1.ShowGrade();
    14     s2.ShowGrade();
    15 }

    输出:

    zhangsan has grade of 80.
    lisi has grade of 59.
    zhangsan has grade of 99.
    lisi has grade of 59.

    这里的要点是,对象 s1 和 s2 都是基于同一个 Student 类创建的,遵循 Student 类提供的相同的抽象。但是对象 s1 和 s2 有自己单独的存储空间,互相不受影响。

    但在 C++ 编译器的实现中,不同对象的成员函数/函数实际上是共享的,只有一个副本。但它显然可以找到调用对象的数据成员,因此可以看起来每个对象拥有一个自己的成员函数。

    这可以提升编译效率,而不会影响 OOP 特性,即数据表示和数据操作都封装到一个对象里面。

    下一篇:C++系列:对象和类(二)

    参考

  • 相关阅读:
    flask数据库操作
    flask之--钩子,异常,上下文,flask-script,模板,过滤器,csrf_token
    Flask项目出现html文件无法自动补全
    pandas强化练习(美国交警开放的数据)
    flask初识
    爬取实时变化的 WebSocket 数据(转载)
    pep8规范
    模拟登陆
    关于在scrapy中使用xpath
    Java基础/利用fastjson序列化对象为JSON
  • 原文地址:https://www.cnblogs.com/noluye/p/12239194.html
Copyright © 2011-2022 走看看