C++语言学习(三)——封装(Encapsulation)

C++语言学习(三)——封装(Encapsulation)

一、封装简介

C语言等面向过程编程中,数据以及数据的相关操作函数都是分离的独立个体;在C++等面向对象编程中,数据以及数据的相关操作被设计为对象,对象包括属性(数据)和操作(函数),两者共同构成对象实体(即类实体)。面向对象编程使程序更模块化,更易读易写,提升了代码重用到一个更高的层次。
面向对象编程中,数据和数据的操作封装为了对象。封装可以隐藏实现细节,使得代码模块化,是把过程和数据包围起来,对数据的访问只能通过已定义的接口。
封装是一种对外提供服务的模型,封装模型是对世间万物的个体抽象。
封装的访问属性如下:
访问属性 属性 对象内部 对象外部
public 公有 可访问 可访问
protected 保护 可访问 不可访问
private 私有 可访问 不可访问
C语言中,struct中所有行为和属性都是public的(默认),既可以使用接口,又可以直接访问其内部数据,没有屏蔽内部数据。
C++语言中,强化了C语言的封装特性,struct、class可以指定行为和属性的访问方式,对内开放数据,对外屏蔽数据,对外提供接口。

二、C语言的封装

C语言中,通常使用模块化进行封装。
stack的C语言实现:

#include <stdio.h>
#include <string.h>

typedef struct stack
{
    char space[1024];
    int top;
}stack;

void stack_init(stack *st)
{
    st->top = 0;
    memset(&st->space, 0, sizeof(st->space));
}

int is_empty(stack *st)
{
    return st->top == 0;
}
int is_full(stack *st)
{
    return st->top == 1024;
}

char pop(stack *st)
{
    return st->space[--st->top];
}

void push(stack *st, char c)
{
    st->space[st->top++] = c;
}

int main(void)
{
    stack st;
    stack_init(&st);
    unsigned int i;
    for(i = ‘a‘; i < (‘z‘ + 1); i++)
    {
        if(!is_full(&st))
            push(&st, i);
    }
    for(i = ‘a‘; i < (‘z‘ + 1); i++)
    {
        printf("%c\n", pop(&st));
    }
    return 0;
}

C语言中封装的struct的数据成员是可以被外部调用修改的。

三、C++语言的封装

1、C++语言的封装

C++语言强化了C语言的封装,在类的表示法中定义了属性和行为的访问级别。
C++语言中,用于表示类属性的变量为成员变量;用于表示类行为的函数为成员函数。C++语言中,可以对类的成员变量和成员函数定义访问级别。
public:使用public关键字声明的类的成员变量和成员函数可以在类的内部和外部访问与调用
private:使用private关键字声明的类的成员变量和成员函数只能在类的内部访问和调用
protected:使用protected关键字声明的类的成员变量和成员函数只能在本类以及派生子类的内部访问和调用。
类的成员的作用域只在类的内部,外部不能直接访问。类的成员函数可以直接访问成员变量和调用成员函数。类的外部可以通过类对象访问public成员。
C++语言中,struct定义的类中成员的默认访问权限为public,class定义的类中成员的默认访问权限为private。

2、C++语言的struct

C++语言中,对struct关键字进行了扩展,struct已经不只是C语言中变量集合的struct,C++语言中的struct不仅可以定义成员函数,也可以实现继承和多态。与C语言中的struct一样,C++语言中使用struct定义类时,成员的默认访问级别为public。

#include <iostream>

using namespace std;

struct Person
{
    const char* name;
    int age;
    virtual void print()
    {
        printf("My name is %s, I‘m is %d years old.\n",name,age);
    }
};
//默认继承访问权限为public
struct Student : Person
{
    void print()
    {
        printf("My name is %s, I‘m is %d years old."
               "My score is %d\n",name,age,score);
    }
    void setScore(const int n)
    {
        score = n;
    }
private:
    int score;
};

int main(int argc, char *argv[])
{
    Person p;
    p.name = "Bob";
    p.age = 30;
    p.print();
    Student s;
    s.name = "Bauer";
    s.age = 20;
    s.setScore(98);
    s.print();
    dynamic_cast<Person*>(&s)->print();
    return 0;
}

3、C++语言的class

由于C++语言的struct需要兼容C语言的struct,C++语言使用新的class关键字定义类。使用class定义类时,成员的默认访问级别为private。
C++中的类支持声明和实现的分离,将类的定义和实现分开,通常.h头文件中只有类的声明,包括成员变量和成员函数的声明;.cpp源文件中完成类的成员函数的实现。

#include <iostream>

using namespace std;

class Person
{
public:
    const char* name;
    int age;
    virtual void print()
    {
        printf("My name is %s, I‘m is %d years old.\n",name,age);
    }
};

class Student : public Person
{
public:
    void print()
    {
        printf("My name is %s, I‘m is %d years old."
               "My score is %d\n",name,age,score);
    }
    void setScore(const int n)
    {
        score = n;
    }
private:
    int score;
};

int main(int argc, char *argv[])
{
    Person p;
    p.name = "Bob";
    p.age = 30;
    p.print();
    Student s;
    s.name = "Bauer";
    s.age = 20;
    s.setScore(98);
    s.print();
    dynamic_cast<Person*>(&s)->print();
    return 0;
}

4、C++语言struct与class的区别

C++语言中struct与class最本质的区别如下:
A、默认访问权限不同。struct默认的访问权限是public的,class默认的访问权限是private的。
B、默认继承访问权限不同。struct默认的继承访问权限是public的,class默认的继承访问权限是private的。
C、class可用作定义模板参数的关键字,而struct不可以。
C++语言中,继承时如果没有指定继承访问权限,默认继承访问权限是public继承还是private继承,取决于子类而不是基类。struct可以继承class,class也可以继承struct,默认的继承访问权限取决于子类是struct还是class,如果子类使用struct声明,默认继承访问权限是public;如果子类使用class声明,默认继承访问权限是private。

#include <iostream>

using namespace std;

class Person
{
public:
    const char* name;
    int age;
    virtual void print()
    {
        printf("My name is %s, I‘m is %d years old.\n",name,age);
    }
};
//默认继承访问权限为public
struct Student : public Person
{
public:
    void print()
    {
        printf("My name is %s, I‘m is %d years old."
               "My score is %d\n",name,age,score);
    }
    void setScore(const int n)
    {
        score = n;
    }
private:
    int score;
};

int main(int argc, char *argv[])
{
    Person p;
    p.name = "Bob";
    p.age = 30;
    p.print();
    Student s;
    s.name = "Bauer";
    s.age = 20;
    s.setScore(98);
    s.print();
    dynamic_cast<Person*>(&s)->print();
    return 0;
}

5、C++语言封装示例

C++类实现stack:
stack.h源码:

#ifndef STACK_H
#define STACK_H

class stack
{
public:
    stack();
    bool is_empty();
    bool is_full();
    void push(char c);
    char pop();
private:
    char space[1024];
    unsigned int top;
};

#endif // STACK_H

stack.cpp源码:

#include "stack.h"
#include <string.h>

stack::stack()
{
    top = 0;
    memset(space, 0, sizeof(space));
}

bool stack::is_empty()
{
    return top == 0;
}

bool stack::is_full()
{
    return top == 1024;
}

void stack::push(char c)
{
    space[top++] = c;
}

char stack::pop()
{
    return space[--top];
}

main.cpp源码:

#include <iostream>
#include "stack.h"
#include <string.h>
using namespace std;

int main()
{
    stack st;
    unsigned int i;
    for(i = ‘a‘; i < ‘z‘ + 1; i++)
    {
        if(!st.is_full())
            st.push(i);
    }
    for(i = ‘a‘; i < ‘z‘ + 1; i++)
    {
        cout<<st.pop()<<endl;
    }
    return 0;
}

C++语言中封装的class stack中数据成员是private的,对于外部不可访问,通过设置数据成员和操作方法的访问权限,可以对外部开放、屏蔽数据成员和操作方法。C++通过定义类成员的访问级别实现封装机制。C++语言中类支持声明和实现的分离,在头文件中声明类,在源文件中实现类。

原文地址:http://blog.51cto.com/9291927/2138820

时间: 2024-08-02 07:44:36

C++语言学习(三)——封装(Encapsulation)的相关文章

【C语言学习】封装和模块化思想

刚学习完C后,做的关于C的课程设计是在一个源文件中放了几百行代码,而且各个功能之间都是相互依赖的,这样就会很麻烦.因为当我要修改某个地方的时候,就会牵连着要修改喝多的地方.而在实际的程序设计中,这也是不可取的.因此,模块化和封装的思想就显得很重要了!!! ★static变量 static变量的一个显著的作用就是可以实现一个模块的封装. static存储类别的特性决定了static声明的全局变量只能被本源文件的函数引用.当在一个源文件中定义一个static全局变量后,其他文件就不能通过使用"ext

Programming With Objective-C---- Encapsulating Data ---- Objective-C 学习(三) 封装数据

Programming with Objective-C Encapsulating Data In addition to the messaging behavior covered in the previous chapter, an object also encapsulates data through its properties. 除了前一章讲述的消息方法(messaging behavior), 对象还能通过它的特性(properties)来封装数据. This chapte

Dart语言学习( 三) Dart数值型

一.类型 数值型有 num,int, double  num a = 10; a = 12.5; print(a); print(a.runtimeType); int b = 20; // b = 20.5; print(b); print(b.runtimeType); double c = 10.5; // c = 30; print(c); print(c.runtimeType); print("\n"); 其中,runtimeType 为运行时的类型. 输出如下: 12.5

OC语言学习 (三) 成员变量get/set方法和“.”语法,@proterty和@synthesize关键字

Person.h #ifndef oc_Person_h #define oc_Person_h @interface Person : NSObject { int age; @protected float height; } - (int) age; //get方法 - (void) setAge:(int)pAge; //set方法 @end #endif Person.m #import <Foundation/Foundation.h> #import "Person.h

Go语言学习——三分钟看透iota

源起枚举 最近做需求时,有一个需要枚举的场景,大概有10+个枚举类型,不愿意像定义一个开关那样敷衍的写成 const ( SwitchOff = 0 SwitchOn = 1 ) 显得不够精致~ 于是想到了iota,深入了解了下,这个小东西好像有点东西. 再回到需求本身——枚举.有了iota,就不用显示定义一大堆数值了. 未使用iota版本 const ( ColorRed = 0 ColorOrange = 1 ColorYellow = 2 ColorGrassland = 3 ColorC

嵌入式linux C++语言(三)——封装(Encapsulation)

嵌入式linux C++语言(三)--封装(Encapsulation) 一.封装简介 C语言等面向过程编程中,数据以及数据的相关操作函数都是分离的独立个体:在C++等面向对象编程中,数据以及数据的相关操作被设计为对象,对象包括属性(数据)和操作(函数),两者共同构成对象实体(即类实体).面向对象编程使程序更模块化,更易读易写,提升了代码重用到一个更高的层次. 面向对象编程中,数据和数据的操作封装为了对象.封装可以隐藏实现细节,使得代码模块化,是把过程和数据包围起来,对数据的访问只能通过已定义的

iOS学习笔记---oc语言第三天

继承.初始化方法 一.继承 继承的上层:父类  继承的下层:子类 继承是单向的,不能相互继承 继承具有传递性:A继承于B,B继承于C,A具有B和C的特征和行为 子类能继承父类全部的特征和行为(私有变量也继承过来了,只是不能访问) 面向对象提供了继承语法.能大大简化代码,把公共的方法和实例对象写在父类里.子类只需要写自己独有的实例变量和方法即可 继承既能保证类的完整,又能简化代码 继承特点 oc中只允许单继承 没有父类的类称为根类,oc中得根类是NSObject(祖宗) 继承的内容:所有的实例变量

JavaScript--基于对象的脚本语言学习笔记(三)

事件处理器 1.一个数据校验表单的例程 <html> <head> <title>js练习</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript"> String.prototype.trim=function(){ r

C语言学习笔记(三) 输入输出函数的基本用法以及运算符

printf() ——将内容输出到显示器上 四种用法 1.printf("字符串");   直接输出字符串 2.printf("输出控制符",输出参数); 3.printf("输出控制符1 输出控制符2",输出参数1,输出参数2); 输出控制符和输出参数的个数必须一致: 4.printf("输出控制符 非输出控制符",输出参数); 输出控制符包含如下: 1.%d —— int 2.%ld ——  long int 3.%c —