1、抽象

  是对具体对象(问题)进行概括,抽出这一类对象的公共性质并加以描述的过程。

1.1 先注意问题的本质描述,其次是实现过程和细节;

1.2 数据抽象:描述某类对象的属性或状态(对象相互区别的物理量);

1.3 代码抽象:描述某类对象共有的行为特征和具体功能;

1.4 抽象的实现:类的声明。

例如:

  钟表抽象:

       数据抽象 int hour; int minute; int second;

代码抽象 settime(); showtime();

抽象实现

 class clock{//钟表类

public://在外界可以访问的,相当于钟表外面可以操作的部分,即接口
void settime(int newh, int newm, int news);
void showtime();//成员函数
private://在类外不能直接操作的,封装的部分,相当于钟表的内部
int hour, int minute, int second;//成员数据};

2、封装:

  将抽象出来的数据成员、代码成员相结合,将它们视为一个整体。

2.1 目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只需要通过外部接口,以特定的访问权限来使用类的成员。

2.2 实现封装:类声明中的{}。

3、继承与派生:

  允许程序员在保持原有类的特性的基础上进行更具体的说明,通过声明派生类来实现。

4、类的多态性:

  同一名称不同功能,达到行为标识的统一,减少程序中标识符的个数,通过重载函数和虚函数来实现。

5、类的声明:

class 类名称{

public: 公有成员(外部接口),任何外部函数都可以访问公有类型的数据和函数;

private:私有成员,只允许本类中的函数访问;

protected:保护性成员,与私有成员类似,差别在于继承与派生时对派生类的影响不同。}

#include<iostream>
using namespace std;
class Clock //时钟类的声明 {
public: //外部接口 //公有成员函数,在类中声明原型,可以在类外给出实现,并在函数名前使用类名加以限制,也可在类内给出,形成内联成员函数,
//允许声明重载函数和带默认形参值的函数 void SetTime(int NewH=0, int NewM=0, int NewS=0);
void ShowTime();
private: //私有数据成员,成员数据与一般变量声明相同,但需要放在类的声明体中
int Hour,Minute,Second;
};
//时钟类成员函数的具体实现
void Clock::SetTime(int NewH, int NewM, int NewS)
{
Hour=NewH;
Minute=NewM;
Second=NewS;
} inline void Clock::ShowTime()
{
cout<<Hour<<":"<<Minute<<":"<<Second<<endl;
}
//主函数
int main()
{
Clock myClock; //定义类对象即类类型的变量:myClock,
cout<<"First time set and output:"<<endl;
myClock.SetTime(); //设置时间为默认值,在类外访问public成员使用 对象员.成员名
myClock.ShowTime(); //显示时间
cout<<"Second time set and output:"<<endl;
myClock.SetTime(8,30,30); //设置时间为8:30:30
myClock.ShowTime(); //显示时间
}

  

6、构造函数:

  构造函数的作用是在对象被创建时使用特定的值构造对象,或者说将对象初始化为一个特定的状态。在对象创建时由系统自动调用。如果在程序中没有声明构造函数,则系统自动产生一个默认形式的构造函数,构造函数可以使内联函数、重载函数和带默认形参值的函数,构造函数名与类名一致,没有返回值且不用void。

思考:

  当我们声明整型数据时,int i=0;我们给i赋初值0。同样我们声明类的对象的时候也应该可以赋给初值,构造函数就是类对象赋初值的规则。

class Clock
{
public:
Clock(int NewH,int NewM,int NewS);//构造函数
void SetTime(int NewH,int NewM,int NewS);
void ShowTime();
private:
int Hour,Minute,Second;
};
构造函数的实现:
Clock::Clock(int NewH, int NewM, int NewS)
{
Hour= NewH;
Minute= NewM;
Second= NewS;
}

建立对象时构造函数的作用:

int main()
{
Clock c(0,0,0); //隐含调用构造函数,将初始值作为实参。
c.ShowTime();
}

 

7、拷贝构造函数和析构函数:

析构函数

析构函数是一种特殊的成员函数,除具有一般成员函数的特性外,还具有如下特性:

1)、析构函数的函数名必须与其类名相同,不能指定返回类型,也不能使用void。为了能与构造函数相区别,要在函数名前加~(波浪符);

2)、析构函数没有参数,一个类中只能拥有一个析构函数,所以析构函数不能重载。定义格式为: ~类名(){ 函数体 } ;

3)、如果程序员没有定义类的析构函数,系统会自动为类创建一个默认析构函数,形式为: ~类名(){ };

4)、通常为public类型,系统在撤消对象时,自动调用析构函数。也允许显式调用;

5)、用delete运算符删除对象时也会自动调用析构函数 。

当对象要被系统释放时,析构函数被调用,在析构函数中可以做一些善后处理处理的工作,如释放内存。

拷贝构造函数

概念:用一个已有的对象来初始化一个被创建的同类对象,是一种特殊的成员函数。

声明的一般格式: 类名(类名 & 对象名);

利用拷贝构造函数可以实现同类对象的数据传递, 即对象的“克隆”。(注意:与对象赋值的不同) (相对于拷贝构造函数,前面介绍的构造函数被称为普通构造函数)

拷贝构造函数的性质 :

1)、函数名必须与类名相同,并且不指定返回类型;

2)、只有一个参数,是同类的对象的引用;

3)、每一个类中都必须有一个拷贝构造函数。如果类中没有声明拷贝构造函数,编译器就会自动生成一个具有上述形式的公有的拷贝构造函数。

拷贝构造函数被调用的场景:

1)、声明时赋值 Student s1 = s;

2)、作为参数传入,实参给形参赋值 func(s);

3)、作为函数返回值返回,给变量初始化赋值 Student s1 = func(s);

浅拷贝与深拷贝

如果在类的定义里没有提供拷贝构造函数,C++会提供一个默认的拷贝构造函数; 默认拷贝构造函数的拷贝方式是各成员逐一复制,这称为是浅拷贝; 在某些情况下,浅拷贝会产生问题,例如:当一个类在它的构造函数动态分配了内存资源,浅拷贝只会复制该资源的地址,而不会为新建的对象重新分配一个资源,因此,会出现多个对象指向同一个堆空间的地址的现象。

应用举例

  一圆形游泳池如图所示,现在需在其周围建一圆型过道,并在其四周围上栅栏。栅栏价格为35元/米,过道造价为20元/平方米。过道宽度为3米,游泳池半径由键盘输入。要求编程计算并输出过道和栅栏的造价。

#include <iostream>
using namespace std;
const float PI = (float)3.14159; //给出p的值
const float FencePrice = 35.; //栅栏的单价
const float ConcretePrice = 20.; //过道水泥单价
class Circle //声明类Circle 及其数据和方法
{
public: //外部接口
Circle(float r); //构造函数
float Circumference(); //计算圆周长
float Area(); //计算圆面积
private: //私有数据成员
float radius;
};
// 类的实现
Circle::Circle(float r) { radius=r; } // 构造函数初始化数据成员radius
float Circle::Circumference() // 计算圆的周长
{
return 2 * PI * radius;
}
float Circle::Area() // 计算圆的面积
{
return PI * radius * radius;
}
//主函数实现
void main ()
{
float radius;
float FenceCost, ConcreteCost;
cout << "Enter the radius of the pool: "; // 提示用户输入半径
cin >> radius;
Circle Pool(radius); // 声明Circle 对象
Circle PoolRim(radius + 3);
// 计算栅栏造价并输出
FenceCost = PoolRim.Circumference() * FencePrice;
cout << "Fencing Cost is ¥" << FenceCost << endl;
// 计算过道造价并输出
ConcreteCost = (PoolRim.Area() - Pool.Area())*ConcretePrice;
cout << "Concrete Cost is ¥" << ConcreteCost << endl;
}
运行结果
Enter the radius of the pool: 10
Fencing Cost is ¥2858.85
Concrete Cost is ¥4335.39

  

8、组合类中的成员数据时另一个类的对象,可以在已有抽象的基础上实现更复杂的抽象。

类的数据成员可以是数据,当然可以是类的对象,这就是类的组合。

class Point
{ private:
float x,y; //点的坐标
public:
Point(float h,float v); //构造函数
float GetX(void); //取X坐标
float GetY(void); //取Y坐标
void Draw(void); //在(x,y)处画点
};
//...函数的实现略
class Line
{
private:
Point p1,p2; //线段的两个端点,用点类的对象作为线类的数据成员。
public:
Line(Point a,Point b); //构造函数,其初始值是点类的对象。
Void Draw(void); //画出线段
};
//...函数的实现略

  

类组合构造函数不仅需要对本类的基本类型成员数据赋初值,也要对对象成员初始化,声明形式:

类名::类名(对象成员所需形参,本类成员形参):对象1(参数),对象2(参数),……{本类初始化}

class Part  //部件类
{
public:
Part();
Part(int i);
~Part();
void Print();
private:
int val;
};
class Whole
{
public:
Whole();
Whole(int i,int j,int k);
~Whole();
void Print();
private:
Part one;
Part two;
int date;
};
Whole::Whole()
{
date=0;
}
Whole::Whole(int i,int j,int k):
two(i),one(j),date(k)
{}

  

类要先声明后使用,但是如果要在声明之前引用一个类(当两个类之间相互引用的时候),就需要事先说明。比如说:

class B;  //前向引用声明class A
{ public:
void f(B b);
};
class B
{ public:
void g(A a);
}; class Fred;//前向引用声明 ,仅仅声明B是一个类,并没有声明其任何对象,所以也不能再完整声明B之前使用其对象
class Barney { public:
void method()
{
x->yabbaDabbaDo(); //错误:Fred类的对象在定义之前被使用
}
private:
Fred* x;//正确,经过前向引用声明,可以声明Fred类的对象指针
};
class Fred {
public:
void yabbaDabbaDo();
private:
Barney* y;
};

  

 

C++——类与对象的更多相关文章

  1. Java编程里的类和对象

    像我们搞计算机这块的,都知道这么一件事,当前的计算机编程语言主要分为两大块,一为面向过程,二为面向对象.Java就是一门纯面向对象的语言.学习了一个月左右的Java,在下对于Java当中的类和对象有了 ...

  2. Python - 类与对象的方法

    类与对象的方法

  3. C++基础知识(5)---类和对象

    终于把C++中的基础在前面的几篇博客中总结完了,可能还有一些语法还没有总结到,没关系,以后用到了再查资料就好.类是C++中的一个非常重要的概念,这是区别你使用的C++到底是面向过程还是面向对象的一个重 ...

  4. 简述JavaScript对象、数组对象与类数组对象

    问题引出 在上图给出的文档中,用JavaScript获取那个a标签,要用什么办法呢?相信第一反应一定是使用document.getElementsByTagName('a')[0]来获取.同样的,在使 ...

  5. 前端学PHP之面向对象系列第一篇——类和对象

    × 目录 [1]类 [2]成员属性[3]成员方法[4]对象[5]成员访问[6]this 前面的话 面向对象程序设计(OOP)是一种计算机编程架构.计算机程序由单个能够起到子程序作用的单元或对象组成,为 ...

  6. Objective-C Runtime 运行时之一:类与对象

    Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一 ...

  7. [Java入门笔记] 面向对象编程基础(一):类和对象

    什么是面向对象编程? 我们先来看看几个概念: 面向过程程序设计 面向过程,是根据事情发展的步骤,按进行的顺序过程划分,面向过程其实是最为实际的一种思考方式,可以说面向过程是一种基础的方法,它考虑的是实 ...

  8. 解析Java类和对象的初始化过程

    类的初始化和对象初始化是 JVM 管理的类型生命周期中非常重要的两个环节,Google 了一遍网络,有关类装载机制的文章倒是不少,然而类初始化和对象初始化的文章并不多,特别是从字节码和 JVM 层次来 ...

  9. 02OC的类和对象

    这章重点介绍OC的类以及对象,由于C语言是面向过程语言,而OC只是对于C语言多了一些面向对象的特性,所以OC相对于其他面向对象语言,例如C#.Java等没有那么多的语法特性,所以差别还是比较大的. 一 ...

  10. swift基础:第六部分:类与对象

    http://reactnative.cn/docs/0.24/getting-started.html#content(react Native 开发文档) 互联网这个时代,你松懈一天,就会有很多很 ...

随机推荐

  1. Android中饼状图的绘制

    https://blog.csdn.net/cen_yuan/article/details/52204281

  2. exp导出含有双引号的表

    由于ORACLE默认的表名都是不区分大小写,在创建表时,在数据字典中存储的表名为大写.在有些情况下,如果创建的表在表名上加上双引号("),则创建的表其表名在数据字典中不作转换.比如 SQL& ...

  3. navicate 连接mysql8.0,个人踩坑问题汇总

    navicate 连接mysql8.0,个人踩坑问题汇总本文目录:1:安装mysql8.0新增全新验证方式,安装如果不修改mysql连接不上2:mysql启动命令问题3:navicate 运程连接My ...

  4. ajax发送请求下载字节流形式的excel文件

    背景 开发项目中导出功能,因为数据量有点大,所以导出可能需要时间有点长,所以想用ajax异步请求. 存在问题 利用传统的js和jquery提供的ajax相关获取响应的方式是无法实现excel文件下载的 ...

  5. Go 使用小记

    1.不能使用在运行时计算的值实例化这样的数组. 而是使用make初始化具有所需长度的切片. db := ConnMysql() rows, err := db.Query("select r ...

  6. UVA12325-注意提高效率的思路

    题目大意:你有一个体积为N的箱子和两种数量无限的宝物.宝物1的体积为S1,价值为V1:宝物2的体积为S2,价值为V2.输入均为32位带符号的整数.你的任务是最多能装多少价值的宝物?   方法:其实也没 ...

  7. SurfaceView 与view区别详解

    SurfaceView 与view区别详解 https://blog.csdn.net/u011339364/article/details/83347109 2018年10月24日 17:20:08 ...

  8. 权限问题 <customErrors> 标记的“mode”属性设置为“Off”

    引用 权限问题 <customErrors> 标记的“mode”属性设置为“Off”. 权限问题标记的“mode”属性设置为“Off”.说明: 服务器上出现应用程序错误.此应用程序的当前自 ...

  9. 2020牛客寒假算法基础集训营4-D子段异或

    思路 CODE #include <bits/stdc++.h> #define dbg(x) cout << #x << "=" <&l ...

  10. spark-sklearn TypeError: 'JavaPackage' object is not callable

    from sklearn import svm, datasets from spark_sklearn import GridSearchCV from pyspark import SparkCo ...