0
点赞
收藏
分享

微信扫一扫

机器学习入门--循环神经网络原理与实践

南柯Taylor 2024-02-16 阅读 9
c++

C++面向对象程序设计-北京大学-郭炜【课程笔记(二)】

课程链接:程序设计与算法(三)C++面向对象程序设计 北京大学 郭炜
课程PPT:github提供的对应课程PPT

1、结构化程序设计

结构化程序设计的不足

  • 结构化程序设计中,函数和其所操作的数据结构,没有直观的联系。
  • 随着程序规模的增加,程序逐渐难以理解,很难一下子看出来:
    • 某个函数结构到底有哪些函数可以对他进行操作?
    • 某个函数到底是用来操作哪些数据结构的?
    • 任何两个函数之间存在怎样的低哦啊用关系?
    • 结构化程序设计没有“封装”和“隐藏”的概念。要访问某个数据结构中的某个变量,就可以直接访问,那么当该变量的定义有改动的时候,就要把所有访问该变量的语句找出来修改,十分不利于程序的维护、扩充。
    • 难以查错,当某个数据结构的值不正确时,难以找出到底是哪个函数导致的。
    • 结构化程序设计中,随着程序规模的扩大,由于程序大量函数、变量之间的关系错综复杂,要抽取这部分代码,变得十分困难(无法重用)。

2、面向对象的程序设计

2.1、面向对象的程序设计

面向对象的程序模式:(如下图所示)
在这里插入图片描述

2.2、从客观事物抽象出类

在这里插入图片描述

  • 将长、宽变量和设置长、宽,求面积,以及求周长的三个函数“封装”在一起,就能形成一个‘矩形类’。
  • 长、宽变量成为该“矩形类”的“成员变量”,三个函数成为该类的“成员函数”。成员变量和成员函数统称为类的成员。

代码:

#include <iostream> 

class CRectangle
{
    public:
        int w, h;   // 成员变量
        // 三个成员函数
        int Area() {
            return w * h;
        }
        int Perimeter() {
            return 2 * (w + h);
        }
        void Init(int w_, int h_) {
            w = w_; h = h_;
        }
};   //必须有分号

int main()
{
    int w,h;
    CRectangle r;  // r是一个对象
    std::cout << "请输入w和h"<<std::endl;
    std::cin >> w >> h;
    r.Init(w, h);
    std::cout << r.Area() << std::endl << r.Perimeter();
    return 0;
}

//OUT:
请输入w和h
1
3
面积 = 3; 周长 = 8

2.3、对象的内存分配

2.4、对象之间的运算

和结构变量一样,对象之间可以用 “=” 进行赋值,但是不能用“==”,“!=”,“<”,“>=“,”<=“,进行比较,除非这些运算符经过了“重载”。

2.5、使用类的成员变量和成员函数

用法1:对象名.成员名

CRectangle r1, r2;
r1.w = 5;
r2.Init(5, 4);

Init函数作用在r2上,即Init函数执行期间访问的w和h是属于r2这个对象的,执行r2.Init不会影响到r1。

用法2:指针->成员名

CRectangle r1,r2;
CRectangle * p1 = & r1;
CRectangle * p2 = & r2;
p1->w = 5;
p2->Init(5,4);  //Init作用在p2指向的对象上

用法3:引用.成员名

CRectangle r2;
CRectangle & rr = r2;
rr.w = 5;
rr.Init(5,4);  // rr的值变了,r2的值也会随着改变

void PrintRectangle(CRectangle & r)
{
	cout << r.Area() << "," << r.Perimeter();
}
CRectangle r3;
r3.Init(5,4);
printRectangle(r3);

2.6、类成员的可访问范围

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

2.6.1、代码实例

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

class CEmployee { 
    private:
        char szName[30]; //名字
    public :
        int salary; //工资
        void setName(char * name); 
        void getName(char * name);
        void averageSalary(CEmployee e1,CEmployee e2);
};

void CEmployee::setName( char * name) {
    strcpy(szName, name); //ok
}
void CEmployee::getName( char * name) {
    strcpy(name, szName); //ok
} 
void CEmployee::averageSalary(CEmployee e1,CEmployee e2){
    salary = (e1.salary + e2.salary )/2;
}

int main(){
    CEmployee e;
    // strcpy(e.szName,"Tom1234567889"); //编译错, 不能访问私有成员
    e.setName("Tom"); // ok
    e.salary = 5000; //ok
    return 0;
}

知识点扩充:C语言中字符串之间的比较【char*】/【string】

2.6.2、private的意义(隐藏的作用)

2.6.3、成员函数的重载及参数缺省

  • 成员函数也可以重载
  • 成员函数可以带缺省参数
  • 案例如下:
#include <iostream>

class Location {
    private:
        int x, y;
    public:
        void init(int x = 0, int y = 0);
        // 两个valueX是函数重载关系
        void valueX(int val) { x = val; }
        int valueX() { return x; }
};

int main() {
    Location A, B;
    A.init(5);
    A.valueX(6);
    std::cout << A.valueX() ;
    return 0;
}

void Location::init(int x, int y)
{
    x = x;
    y = y;
}

// OUT
6
  • 注意!!!使用缺省参数需要注意避免有函数重载时的二义性
class Location {
    private:
        int x, y;
    public:
        void init(int x = 0, int y = 0);
        
        两个valueX是函数重载关系
        (这里存在二义性)
        void valueX(int val = 0) { x = val; }
        int valueX() { return x; }
};

int main() {
    Location A;
    A.valueX();   Error,编译起无法判断调用哪个valueX
    return 0;
}
举报

相关推荐

0 条评论