面向对象的基本概念

一、结构化程序设计

结构化程序设计方法,也称为面向过程的设计方法。它强调数据类型和程序结构,注重程序的易读性、可靠性和可维护性。
在结构化程序设计中,采用 自顶向下逐步求精模块化的思想。

程序设计的过程基本上就是编写函数的过程。

程序基本上都含有顺序选择循环3种基本控制结构。
程序化结构设计主要强调的就是程序的易读性。
基本思想:数据结构+算法=程序。

二、面向对象程序设计的概念和特点

是20世纪90年代以来软件开发方法的主流。

所谓面向对象的程序设计方法,就是使分析、设计和实现一个系统的方法尽可能地接近人们认识一个系统的方法。通常包括:面向对象的分析面向对象的设计面向对象的程序设计

对象具有两个特性:
1.状态:是指对象本身的信息,也称为属性。
2.行为:是对对象的操作。

类是面向对象程序设计方法中的程序主体。

面向对象的程序设计有:抽象封装继承多态4个基本特点。

在面向对象程序设计中,将一组数据和这组数据有关的操作集合组装在一起形成对象,叫做抽象。

对象的特点:属性和操作。

把对象的属性和操作结合成一个独立的系统单位,并尽可能隐蔽对象的内部细节叫做封装。
C++语言通过建立用户定义的类来支持数据封装和信息隐藏。

继承是面向对象程序设计的一个重要特性,是软件复用的一种形式,它允许在原有类的集成上创建新的类。

多态是指不同种类的对象都具有名称相同的行为,而具体行为的实现方式却有所不同。

三、类的初步认识

在C++中,向int或double这样的类型是系统预定义的,称为基本数据类型。

类以数据为中心,把相关的一批函数组成为一体。
定义类以称为说明类。
在C++中,类定义的一般格式

class 类名
{
  访问范围说明符:
        成员变量1
        成员变量2
        ...
        成员函数声明1
        成员函数声明2
        ...
  访问范围说明符:
      更多成员变量
      更多成员函数声明
      ...
};

类以关键字class开始,后面是类名。类名的定义遵循一般的标识符命名规则,即字母、下划线和数字的组合,大小写敏感,但不能以数字开头,也不能和系统中使用的关键字完全相同。
类是具有唯一标识符的实体,类名不能重复。

访问范围说明符一共有public(公有)private(私有)protected(保护)3种。

成员变量是类中的一类成员,个数不限,也称为数据成员。代表对象的属性。声明方式与普通变量的声明相同。

在C++98标准下,类中声明的任何成员不能使用auto、extern和register关键字进行修饰。

如果成员函数定义在类体外,则类体内必须要有函数原型,类体外函数定义的前面必须用“类名::"来限定

返回值类型 类名::成员函数名(参数列表)
{
  成员函数的函数体
}

在一般情况下,将类的成员变量声明为私有的,以便隐藏数据。

程序2-1定义一个表示日期的类myDate。3个基本属性:年、月、日,用year、month和day表示。

程序2-1 定义日期类myDate

#include <iostream>
using namespace std;
class myDate
{
    public:
        myDate();       //构造函数
        myDate(int,int,int);    //构造函数
        void setDate(int,int,int);  //设置日期
        void setDate(myDate);    //设置日期
        myDate getDate();   //获取日期
        void setYear(int);  //设置年
        int getMonth();//获取月
        void printDate() const;     //打印日期
    private:
        int year,month,day;     //成员变量,表示年、月、日 
 };
//在类体外定义成员函数
myDate::myDate()
{
    year = 1997,month = 2,day = 12;
 } 
myDate::myDate(int y,int m,int d)
{
    year = y;month = m;day = d;
}
void myDate::setDate(int y,int m,int d)
{
    year=y;month=m;day=d;
    return;
}
void myDate::setDate(myDate oneD)
{
    year=oneD.year;month=oneD.month;day=oneD.day;
    return;
}
myDate myDate::getDate()
{
    return *this;
}
void myDate::setYear(int y){
    year = y;
    return; 
}
int myDate::getMonth()
{
    return month;
}
void myDate::printDate() const
{
    cout<<year<<"/"<<month<<"/"<<day;
    return;
}

程序2-2 定义学生类Student

class Student
{
    public:
        void setStudent(string,myDate); //设置学生信息
        void setName(string);           //设置学生姓名
        string getName();               //获取姓名
        void setBirthday(myDate);       //设置生日
        myDate getBirthday();           //获取生日
        void printStudent() const;      //打印信息
    private:
        string name;        //姓名
        myDate birthday;        //生日 
};
//在类体外定义成员函数
void Student::setStudent(string s,myDate d)
{
    name = s;
    birthday.setDate(d);
    return;
}
void Student::setName(string n)
{
    name = n;
    return;
}
string Student::getName()
{
    return name; 
}
void Student::setBirthday(myDate d)
{
    birthday.setDate(d);
    return;
}
myDate Student::getBirthday()
{
    return birthday;
}
void Student::printStudent() const
{
    cout<<"姓名:"<<name<<"\t生日:";
    birthday.printDate();   //调用类myDate的成员函数 
    cout<<endl; 
 } 

四、类的示例程序剖析

(一)、程序结构

一个完整的C++程序包括以下儿部分。
●一个主函数,可以调用其他函数,但不能被调用,也称为主程序。
●用户定义的任意多个的类及全局函数。
●全局说明。在所有函数和类定义之外的变量说明及函数原型。
●注释。
●头文件。

从逻辑关系上看,典型的C++程序的结构包括类的定义类中成员函数的实现主函数main

成员变量一般均定义为私有访问权限,仅能在本类内访问。如果要从类外访问,则需要为成员变量定义相应的访问函数,然后通过访问函数来访问私有的成员变量。

实现成员函数时要指明类的名称,

返回值类型 类名::函数成员名(参数表)
{
   函数体
}

定义一个普通对象,即类变量的基本方法有两种。
(1)

类名 对象名;
或是
类名 对象名(参数);
或是
类名 对象名 = 类名(参数);

(2)

类名 *对象指针名 = new 类名;
或是
类名 *对象指针名 = new 类名();
或是
类名 *对象指针名 = new 类名(参数);

用new创建对象时返回的是一个对象指针,这个指针指向本类刚创建的这个对象。
C++分配给指针的仅仅是存储指针值的空间,而对象所占用的空间分配在堆上。

声明对象引用即变量别名的基本格式

类名 &对象引用名 = 对象;

声明对象指针,即指向对象的指针的基本格式
类名 对象指针名 = 对象的地址;

声明对象数组的格式
类名 对象数组名[数组大小];

同类型的对象之间可以相互赋值。例如,定义了类C后,

C a1,b1;  //定义了C类的对象a1和b1
C *p = &a1;  //定义了指向对象a1的C类类型的指针p
C &R = b1;  //定义了C类类型对象b1的引用R 
C A[3];  //定义了C类类型对象的数组A,含3个元素

程序运行中,创建对象就是为对象分配内存。

五、访问对象的成员

使用对象访问成员变量与调用成员函数

通过对象访问成员变量的一般格式:

对象名.成员变量名

调用成员函数的格式

对象名.成员函数名(参数表)

例如,可以写一个驱动程序。
程序2-3 验证类功能的驱动程序

#include <iostream>
#include <string>
#include "myDate.cpp";
#include "Student.cpp";
using namespace std;

int main() {
    Student ss;
    int y,m,d;
    string name_;
    cout<<"请输入学生的姓名和生日,生日以\”年 月 日\"的次序输入:";
    cin>>name_>>y>>m>>d;
    ss.setStudent(name_,myDate(y,m,d));
    ss.printStudent();
    return 0;
} 

请输入学生的姓名和生日,生日以”年 月 日"的次序输入:
薛怀 1997 02 12
姓名:薛怀      生日:1997/2/12

使用指针访问对象的成员

如果是通过指针访问成员变量,则点运算符.换位箭头运算符->

指针->成员名

程序2-4 使用指针方式的驱动程序

#include <iostream>
#include <string>
#include "myDate.cpp";
#include "Student.cpp";

int main()
{
    Student ss;
    int y,m,d;
    string name_;
    Student *sp = &ss;  //指向ss的指针sp
    
    cout<<"请输入学生的姓名和生日,生日以\”年 月 日\"的次序输入:";
    cin>>name_>>y>>m>>d;
    sp->setStudent(name_,myDate(y,m,d));
    sp->printStudent();
    return 0;
}

使用引用访问对象的成员

可以在程序中直接定义引用并进行初始化。
程序2-5 使用引用方式的驱动程序

#include <iostream>
#include <string>
#include "myDate.cpp";
#include "Student.cpp";

int main()
{
    Student ss;
    int y,m,d;
    string name_;
    Student &sy = ss;   //ss的别名sy 
    
    cout<<"请输入学生的姓名和生日,生日以\”年 月 日\"的次序输入:";
    cin>>name_>>y>>m>>d;
    sy.setStudent(name_,myDate(y,m,d));
    sy.printStudent();
    return 0;
}

六、类成员的可访问范围

访问范围说明符的含义

public的含义是公有的,使用它修饰的类的成员可以在程序的任何地方被访问。
private的含义是私有的,使用它修饰的类的成员仅能在本类内被访问。
protected的含义是保护的,它的作用介于public和private之间,使用它修饰的类的成员能在本类内及子类中被访问。
如果某个成员前面没有访问范围说明符,则默认该成员为私有成员。
例2-7 访问范围说明符

class Line
{
    private:
        double length;
    public:
        void setLength(double);
        double getLength();
    private:
        double area;
        bool isEmpty();
};

例2-8
class A
{
        int m,n;
    public:
        int a,b;
        int func1();
    private:
        int c,d;
        void func2();
    public:
        char e;
        int f;
        int func3();
};

成员的访问

程序2-6 类成员的访问

#include <iostream>
using namespace std;
class Box
{
    public:             //公有的
        double length;
        void setWidth(double wid);
        double getWidth();
    private:        //私有的 
        double width;
};
//类体外定义成员函数
double Box::getWidth()
{
    return width;
 } 
void Box::setWidth(double wid)
{
    width = wid;
}
int main()
{
    Box box;        //声明一个对象
    //不使用成员函数设置长度
    box.length = 10.0;      //正确,因为length是公有的
    cout<<"Length of box:"<< box.length<<endl;      //输出Length of box:10
    //不使用成员函数设置宽度
//  box.width = 10.0;   //错误,因为width是私有的
    box.setWidth(10.0); //必须使用成员函数设置宽度
    cout<<"Width of box:"<<box.getWidth()<<endl;    //输出Width of box:10
    return 0; 
}

程序2-7 类成员访问示例

#include <iostream>
#include <string>
using namespace std;

class CEmployee
{
    private:
        string szName;      //姓名
        int salary;     //工资
    public:
        void setName(string);   //设置姓名
        string getName();   //获取姓名
        void setSalary(int);    //设置工资
        int getSalary();    //获取工资
        int averageSalary(CEmployee);   //计算两人的平均工资 
};

void CEmployee::setName(string name)
{
    szName = name;
}
string CEmployee::getName()
{
    return szName;
}
void CEmployee::setSalary(int mon)
{
    salary = mon;
}

int CEmployee::getSalary()
{
    return salary;
}

int CEmployee::averageSalary(CEmployee e1)
{
    return (salary + e1.getSalary())/2;
}

int main()
{
    CEmployee eT,eY;        
    //eT.szName = "Tom1234567";     //编译错误,不能直接访问私有成员
    eT.setName("Tom1234567");   //需要通过公有成员函数访问
    //eT.salary = 5000; //编译错误,不能直接访问私有成员
    eT.setSalary(5000);
    cout<<eT.getName()<<endl; 
    eY.setName("Yong7654321");  //需要通过公有成员函数访问
    eY.setSalary(3500);
    cout<<eY.getName()<<endl; 
    cout<<"aver="<<eT.averageSalary(eY)<<endl;
    return 0;
}

输出结果:
Tom1234567
Yong7654321
aver=4250

隐藏的作用

设置私有成员的机制叫做“隐藏”。目的是强制对私有成员变量的访问一定要通过公有成员函数进行。
假设需要修改程序2-7,例如,在系统内部对姓名统一加一个前缀“E-”,但不对外展示这个前缀,只需要修改函数setName()和getName()

void CEmployee::setName(string name)
{
    szName = "E-" + name;
    cout<<"name="<<szName<<endl;
}
string CEmployee::getName()
{
    return szName.substr(2);
}

七、标识符的作用域与可见性

标识符的作用域是指标识符的有效范围,即它在程序中的存在区域。
标识符的可见性是指在程序的哪个区域里可以使用。

C++中标识符的作用域有函数原型作用域局部作用域(块作用域)类作用域命名空间作用域

函数原型作用域

是C++程序中最小的作用域。在声明函数原型时形参的作用范围就是函数原型作用域。例如

double ares(double radius);

局部作用域

程序中使用相匹配的一对大括号括起来的一段程序称为块。作用域局限在块内的称为局部作用域。
具有局部作用域的变量也称为局部变量。

类作用域

命名空间作用域

具有命名空间作用域的变量也称为全局变量。

对于在不同的作用域声明的标识符,可见性的一般原则如下:
●标识符要声明在前,引用在后。
●在同一个作用域中,不能声明同名的标识符。在没有互相包含关系的不同作用域中声明的同名标识符,互不影响。
●如果存在两个或多个具有包含关系的作用域,外层声明了一个标识符,而内层没有再次声明同名标识符,那么外层标识符在内层仍然可见。如果在内层声明了同名标识符,则外层标识符在内层不可见,这时称内层标识符隐藏了外层同名标识符,这种机制称为隐藏规则。
程序2-8 作用域隐藏规则

#include <iostream>
using namespace std;

int main()
{
    int a = 1;
    cout<<a<<"\n";
    for(int i = 1;i<2;i++)
    {
        int a = 2;
        cout<<a<<"\n";
    }
    cout<<a<<"\n";
    return 0;
}

例题,输出程序结果

#include <iostream>
using namespace std;
class Test
{
    int a,b;
    int getmin()
    {
        return (a<b?a:b);
    }
    public:
        int c;
        void setValue(int x1,int x2,int x3)
        {
            a=x1;b=x2;c=x3;
        }
        int GetMin();
};
int Test::GetMin()
{
    int d = getmin();
    return (d = d<c?d:c);
}
int main()
{
    Test t1;
    t1.setValue(34,6,2);
    cout<<t1.GetMin()<<endl;
}

输出结果:
2

#include <iostream>
using namespace std;
class MyClassType1
{
    private:
        int x,y;
    public:
        int getx()
        {
            return x;
        }
        int gety();
        void setx(int x0)
    {
        x = x0;
    }
    void sety(int y0);
    void displayx()
    {
        cout<<"x="<<x<<endl;
    }
    void displayy()
    {
        cout<<"y="<<y<<endl;
    }
};

int MyClassType1::gety()
{
    return y;
}
void MyClassType1::sety(int y0)
{
    y = y0;
}

int main()
{
    MyClassType1 obj1,*p,objArr[10];
    obj1.setx(111);
    cout<<obj1.getx()<<endl;
    obj1.displayx();
    
    p = new MyClassType1;
    (*p).setx(56);
    p->sety(78);
    int k = (*p).getx();
    int m = p->gety();
    cout<<"k="<<k<<endl;
    cout<<"m="<<m<<endl;
    
    for(int i = 0;i<5;i++)
    {
        objArr[i].setx(i+10);
        objArr[i].sety(i+20);
    }
    p = &objArr[9];
    while(p>=&objArr[5])
    {
        p->setx(88);
        p->sety(99);
        p--;
    }
    for(int i = 0;i<10;i++)
    {
        cout<<objArr[i].getx()<<"   "<<objArr[i].gety()<<endl;
    }
}

输出结果:
111
x=111
k=56
m=78
10   20
11   21
12   22
13   23
14   24
88   99
88   99
88   99
88   99
88   99

程序设计

/*
*   04737 c++ 自学考试2019版 第二章课后练习
*   程序设计题 1
*   需求:设计并实现一个类Course.它代表学校中的一门课程..... 
*/

//标准流 
#include<iostream>
//标准字符
#include<string> 
using namespace std;

class Course{
    private:
        //课程名 
        string courseName;
        //学分 
        int score; 
        //学时数
        int hours;
        //课程类别
        string category;
        //授课专业 
        string professional;
    public:
        //无参构造器
        Course(); 
        //有参构造器
        Course(string courseName,string category,string professional,int score,int hours);
        //声明getter
        string getCourseName();
        string getCategory();
        string getProfessional();
        int getScore();
        int getHours();
        //声明setter
        void setCourseName(string str);
        void setCategory(string str);
        void setProfessional(string str);
        void setScore(int a);
        void setHours(int a);
        //声明 打印所有数据函数 
        void showInfo(); 
};
//定义无参构造
Course::Course()
{
    cout<<"The no-argument constructor is running"<<endl;
}
//定义有参构造
Course::Course(string courseName_,string category_,string professional_,int score_,int hours_)
{
    courseName = courseName_;
    category = category_;
    professional = professional_;
    score = score_;
    hours = hours_;
}
//定义 getter
string Course::getCourseName(){return courseName;}
string Course::getCategory(){return category;}
string Course::getProfessional(){return professional;}
int Course::getScore(){return score;}
int Course::getHours(){return hours;} 
//定义 setter
void Course::setCourseName(string str){courseName = str;}
void Course::setCategory(string str){category = str;}
void Course::setProfessional(string str){professional = str;}
void Course::setScore(int a){score = a;}
void Course::setHours(int a){hours = a;}
//定义 打印所有数据函数
void Course::showInfo()
{
    cout<<"print all the infomation"<<endl;
    cout<<"courseName="<<courseName<<endl;
    cout<<"category="<<category<<endl;
    cout<<"professional="<<professional<<endl;
    cout<<"score="<<score<<endl;
    cout<<"hours="<<hours<<endl;
} 

//主函数测试
int main()
{
    Course test("c++程序设计","c++","计算机科学技术",80,60);
    test.showInfo();
}

输出结果
print all the infomation
courseName=c++程序设计
category=c++
professional=计算机科学技术
score=80
hours=60
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,188评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,464评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,562评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,893评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,917评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,708评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,430评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,342评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,801评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,976评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,115评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,804评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,458评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,008评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,135评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,365评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,055评论 2 355

推荐阅读更多精彩内容

  • 结构化程序设计 在结构化程序设计中,采用自顶向下、逐步求精和模块化的思想,将复杂的大问题层层分解为许多简单的小问题...
    silasjs阅读 923评论 0 3
  • 面向对象的基本概念 程序化结构设计 在程序化结构设计中,采用 自顶向下、逐步求精及模块化 的思想 在编写程序时,使...
    陈_MY阅读 496评论 0 0
  • 面向对象的基本概念 1. 简述 C 和 C++ 有何不同? 宏观上: C 语言属于面向过程语言,通过函数来实现程序...
    MinoyJet阅读 1,126评论 0 0
  • 一基本特征 面向对象的基本特征有三个:封装性,继承性,多态性 封装性 封装是一种信息隐藏技术,封装使数据和加工数...
    邹小月阅读 583评论 0 2
  • 面向对象的基本概念有对象、类、抽象、封装、继承、多态、接口、消息、组件、模式和复用等。 1.对象 对象是由数据及其...
    everfight阅读 1,192评论 0 0