程序设计基础II学习笔记

第一章 面向对象程序设计概述

面向对象的语言

  • 是高级语言。
  • 将客观事物看做具有属性和行为的对象。
  • 通过抽象找出同一类对象的共同属性和行为,形成类。
  • 通过类的继承和多态实现代码的重用
  • 使得代码具有独立性、模块性。利于维护和修改。

:钟表。(本质特征:都是看时间)


对象(类的实例):某块特定的钟表。(颜色、形状等可能不一样)


:分类的主要依据:抽象。例如:石头、汽车、树木等都是人们长期的生产生活中抽象出来的概念。


类与对象的关系:犹如模具与铸件的关系,一个属于某类的对象称为该类的一个示例。


封装:尽可能简化内部细节。对外形成一个边界,只保留有限的对外接口使之可以与外部发生反应。例如:sort函数就是一个封装好的函数,直接输入地址就可以对数组进行排序。


继承:特殊类拥有一般类的全部属性与服务,我们称为特殊类对一般类的继承。例如:轮船是一般类,客船是特殊类。(a是一般类,如果b有a全部属性特点,在此基础上,b还有特殊的属性,那么b就是特殊类。)


源程序:还没翻译的代码。(机器无法识别)


目标程序:源程序经过翻译生成的程序,可以直接执行。


翻译程序

  • 汇编程序:将汇编语言写的源程序翻译成目标程序。(高级语言用不到)
  • 编译程序:将高级语言写的源程序翻译成目标程序。(C、C++)
  • 解释程序:与编译程序的不同点:编译程序一次性将汇编程序翻译完,解释程序翻译一句、执行一句,反复进行。(JAVA、BASIC)

程序的开发过程:(C++为例)

  • 1.编辑:将源程序输入到计算机中,生成后缀为cpp的磁盘文件。
  • 2.编译:将程序的源代码转换为机器语言代码。
  • 3.连接:将多个源程序文件以及库中的某些文件连接在一起,生成一个后缀为exe的可执行文件。
  • 4.运行调试

第二章 面向对象程序设计基础


cin和cout基本输入和输出:getline(cin,str):输入带空格字符串。


常变量的定义:const 变量类型 变量名=x(所定义的变量为常量)


引用与常引用:(对一块地址重复命名)

    int n = 10;
    int &a = n;       //引用
    const int &b = n; //常引用
    cout << a << ' ' << b << endl;

内联函数:系统直接将调用内联函数的地方用等价的语句替换,减少运行环境的保存和恢复时间。(在函数名前面加上inline即是内联函数,但是内联函数只适合小功能的函数,例如一个计算公式等)


带缺省值的函数:预先给定形参值,如果不给定实参值,则采用形参值。

在这里插入图片描述
在这里插入图片描述


函数重载:多个 参数数量 或参数类型 不同的函数 函数名相同


动态内存分配(注意:返回的是分配的空间的首地址)

  • 单个元素的内存分配:
   int *p, *q;
   p = new int(3);//初始化该空间的值为3
   q = new int;
   delete[] p;
   delete[] q;
  • 多个元素的内存分配:
    int *p, *q;
    p = new int[10]; //分配10个int型的元素,把该内存的首地址给p
    q = new int;
    delete[] p;
    delete[] q;

动态内存的释放:delete

    int *p, *q;
    p = new int[10];
    q = new int;
    delete[] p; //多个元素的动态内存释放
    delete q;   //单个元素的动态内存释放

第三章 类和对象(一)

c++面对对象程序设计,也使用了类和对象的概念,并通过下面的方法来模拟对象的状态和行为:

  • 1.对象的状态通过对象的属性数据来描述。
  • 2.对象的行为:定义一个函数集,通过调用对应函数表示对象完成一个行为。

:由成员变量(数据成员)和成员函数组成

对象的定义:类名 对象名(形如int a、double a)。

对象的访问:

  • 对象名.成员变量名
  • 指向对象的指针名->成员变量名
  • 对象名.成员函数名
  • 指向对象的指针名->成员函数名

代码示例:

	class student
	{
	public:
	    int score;
	    string name;
	    void change_score(int a)
	    {
	        score = a;
	    }
	    void change_name(string a)
	    {
	        name = a;
	    }
	};
	int main()
	{
	    student a;
	    a.change_score(100);
	    a.change_name("hesor");
	    cout << a.name << ' ' << a.score << endl;
	    return 0;
	}
/*
Output:
hesor 100
*/

构造函数:主要用来初始化对象的数据成员,构造函数可以重载。构造函数没有函数返回类型,且函数名与类名相同。

代码示例
class student
{
public:
    int score;
    string name;
    student()
    {
        score = 10;
        name = "orz";
    }
    student(int s, string n)
    {
        score = s;
        name = n;
    }

    void change_score(int a)
    {
        score = a;
    }
    void change_name(string a)
    {
        name = a;
    }
};
int main()
{
    //调用无参构造函数 注意:不是student a()
    student a;
    student b(100, "hesor");
    cout << a.name << ' ' << a.score << endl;
    cout << b.name << ' ' << b.score << endl;
    return 0;
}
/*
Output:
orz 10
hesor 100
*/

类的访问控制

  • public:公有成员,在程序的任何地方都可以访问。一般作为类与外界的接口。
  • private:私有成员,只能被该类的成员函数或该类的友元访问。
  • protect:保护成员,与私有成员差不多,主要在继承方面有区别,(派生类可以访问基类的保护成员,但是不能访问基类的私有成员)。

析构函数:析构函数和构造函数类似,不过构造函数是在创建对象的时候自动调用,而析构函数是在销毁对象的时候程序自动调用。但是析构函数需在函数名前加上~,并且析构函数没有参数(因此析构函数不能重载)。


拷贝构造函数:一种特殊的构造函数,用一个已存在对象来初始化正在创建的新对象。


类的继承:A类继承B类,B叫做基类,A叫做派生类(也叫做父类与子类)。

class student : public person
{
};
上面就是以persoon类为基类,student为派生类的公有继承方式,student类自动继承person类中的所有属性和方法(可以根据需要在派生类中添加属性和方法)。

派生类构造函数

class person
{
public:
    string name;
    int high;
    person(string a, int h)
    {
        name = a;
        high = h;
    }
};
class student : public person
{
public:
    int score;
    // student(int a)  //1
    // 如果采用 1 这种派生类的构造函数,那么基类默认使用无参构造函数初始化从基类继承的成员
    student(int a) : person("hesor", 170) //派生类构造函数
    {
        score = a;
    }
};
main()
{
    student a(100);
    cout << a.name << ' ' << a.score << ' ' << a.high << endl;
    return 0;
}
/*
Output:
hesor 100 170
*/

派生类构造函数:与基类构造函数一样,但是需要注意一点:派生类析构函数调用的时候基类中的析构函数也会调用!

class person
{
public:
    string name;
    int high;
    person(string a, int h)
    {
        name = a;
        high = h;
    }
    ~person()
    {
        cout << "基类 end... ..." << endl;
    }
};
class student : public person
{
public:
    int score;
    // student(int a)  //1
    // 如果采用 1 这种派生类的构造函数,那么基类默认使用无参构造函数初始化基类成员变量
    student(int a) : person("hesor", 170) //派生类构造函数
    {
        score = a;
    }
    ~student()
    {
        cout << "派生类 end... ..." << endl;
    }
};
main()
{
    student a(100);
    cout << a.name << ' ' << a.score << ' ' << a.high << endl;
    return 0;
}
/*
Output:
hesor 100 170
派生类 end... ...
基类 end... ...
*/

函数重定义:派生类对基类中继承过来的函数进行重新定义(要求函数返回值、参数个数、参数类型完全一致)。

class person
{
public:
    void f()
    {
        cout << "基类" << endl;
    }
};
class student : public person
{
public:
    void f()
    {
        cout << "派生类" << endl;
    }
};
main()
{
    student a;
    person b;
    a.f();
    b.f();
    return 0;
}
/*
Output:
派生类
基类
*/

多重继承下的派生类的定义

class student
{
public:
    void f_student()
    {
        cout << "我是学生" << endl;
    }
};
class teacher
{
public:
    void f_teacher()
    {
        cout << "我是老师" << endl;
    }
};
class student_teacher : public student, public teacher
{
};
main()
{
    student_teacher a;
    a.f_student();
    a.f_teacher();
    return 0;
}
/*
Output:
我是学生
我是老师
*/

注意,在继承时,总是先调用基类的构造函数再调用派生类的构造函数,多重继承时,按照继承基类的顺序调用构造函数。析构函数的调用顺序恰好与构造函数的调用规律相反。

多重继承中的二义性问题:由于多重继承有多个基类,基类的属性名和方法名可能重复,所以派生类中会产生二义性问题。例如下图,若A有成员变量name,BC继承了A之后 都会有变量 name,然后 D又多重继承了BC,那么D就会有两个name变量,调用的时候就会产生二义性。

A
B
C
D

解决方法

  • 通过作用域运算符指定要调用哪个基类的属性和方法:
class person
{
public:
    int NUM = 123456;
};
class student : public person
{
};
class teacher : public person
{
};
class student_teacher : public student, public teacher
{
};
main()
{
    student_teacher a;
    cout << a.teacher::NUM;
    return 0;
}
/*
Output:
123456
*/
  • 虚拟继承:加入virtual关键字,将图中的A类定义为虚基类,虚基类的成员在类的继承关系中只会被继承一次。
class person
{
public:
    int NUM = 123456;
};
class student : virtual public person
{
};
class teacher : virtual public person
{
};
class student_teacher : public student, public teacher
{
};
main()
{
    student_teacher a;
    cout << a.NUM;
    return 0;
}
/*
Output:
123456
*/

更新ing… …

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hesorchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值