当前位置: 首页 > article >正文

C++类与对象学习笔记(一)

https://www.bilibili.com/video/BV1jm4y1w7pa?spm_id_from=333.788.player.switch&vd_source=e8984989cddeb3ef7b7e9fd89098dbe8&p=6
🚩​🚩🚩来自b站“码农论坛”的视频“类与对象”做的笔记🚩​🚩🚩

类与对象

    • 1-1 cpp结构体的成员函数
    • 1-2 对象和类-类的访问权限
    • 1-3 对象和类-简单使用类
    • 1-4 构造函数和析构函数

1-1 cpp结构体的成员函数

在 C 语言中,结构体不能包含函数。
C 语言的结构体只能用于存储数据,不能直接定义逻辑或操作。
尽管你可以将函数指针存储在结构体中,以间接实现某种形式的“行为”,但这不是将函数作为结构体的成员。

#include <stdio.h>  
// 定义一个结构体  
struct Point {  
    int x;  
    int y;  
};  
 
// 定义一个函数  
void printPoint(struct Point p) {  
    printf("Point(%d, %d)\n", p.x, p.y);  
}  
 
int main() {  
    struct Point p1 = {10, 20};  
    printPoint(p1); // 使用函数  
    return 0;  
}

在这个示例中,struct Point 只包含数据成员,其逻辑是通过外部函数来实现的。

//在 C++ 语言中,结构体(struct)可以包含成员函数。
//这使得结构体不仅可以存储数据,还可以对这些数据进行操作。
//C++ 的结构体和类(class)之间的主要区别只是默认的访问控制:结构体成员默认是公共的,而类成员默认是私有的。
#include <iostream>  
using namespace std;  
 
// 定义一个结构体  
struct Point {  
    int x;  
    int y;  
 
    // 成员函数  
    void print() {  
        cout << "Point(" << x << ", " << y << ")" << endl;  
    }  
};  
 
int main() {  
    Point p1 = {10, 20};  
    p1.print(); // 调用成员函数  
    return 0;  
}

在这个示例中,struct Point 包含一个成员函数 print(),该函数可以访问和操作结构体的成员 x 和 y。
结构体(struct)在C语言和C++中的其他差异
访问控制‌:C语言中的结构体没有访问控制的概念,所有成员默认都是公有的;而C++中的结构体可以有访问控制,默认情况下成员是公有的‌。

继承‌:C语言不支持继承,因此结构体不能作为其他结构体或类型的基类;而C++支持继承,结构体可以作为基类‌。

构造函数和析构函数‌:C语言中没有构造函数和析构函数的概念;而C++中的结构体可以有构造函数和析构函数‌。

类型兼容性‌:C语言中的结构体类型严格依赖于其声明,即使成员列表相同,两个不同的结构体类型也不兼容;而C++中的结构体支持类型兼容性,如果两个结构体具有相同的成员列表,则它们是兼容的‌。

命名空间‌:C语言没有命名空间的概念,所有的结构体定义都在全局作用域内;而C++支持命名空间,允许将结构体定义组织在不同的命名空间中,以避免命名冲突‌。

//在CPP中,结构体就是类,把定义结构体的关键字改成class
#include <iostream>  
using namespace std;  
// 结构体变类:1.将struct改成class 2.将class里面加上public:
class Point {
public:  
    int x;  
    int y;  
 
    // 成员函数  
    void print() {  
        cout << "Point(" << x << ", " << y << ")" << endl;  
    }  
};  
 
int main() {  
    Point p1;
    p1 = {10, 20};  
    p1.print(); // 调用成员函数  
    return 0;  
}
//1.类的成员函数可以在类的外面,加类名和:: 2.在类里面只需要写函数的声明即可
class Point {
public:  
    int x;  
    int y;  

    // 成员函数  
    void print();
};  

void Point::print() {  
    cout << "Point(" << x << ", " << y << ")" << endl;  
}  

int main() {  
    Point p1;
    p1 = {10, 20};  
    p1.print(); // 调用成员函数  
    return 0;  
}

1-2 对象和类-类的访问权限

  1. 类的成员有三种访问权限:public、private和protected,分别表示公有的、私有的和受保护的。
  2. 在类的内部(类的成员函数中),无论成员被声明为public还是private,都是可以访问。
  3. 在类的内部(定义类的代码之外),只能访问public成员,不能访问private,protected成员。
  4. 在一个类体的定义中,private和public可以出现多次。
  5. 结构体的成员缺省为public,类的成员缺省为private。eg.: 对类来说,所有的成员都是私有的,在main函数中无法直接访问
  6. private的意义在于隐藏类的数据和实现,把需要向外暴露的成员声明为public。
#include <iostream>  
using namespace std;  

class Point {
public:  
    int x;  
    int y;

    void print();// 成员函数  
};  

void Point::print() {  
    cout << "Point(" << x << ", " << y << ", "<< z <<")" << endl;  
}  

int main() {  
    Point p1;
    p1 = {10,20};  
    p1.print(); // 调用成员函数    
    return 0;  
}

1-3 对象和类-简单使用类

编程思想和方法的改变,披着C++外衣的C程序员

1.类的成员函数可以直接访问该类其它的成员函数(可以递归)。

2.类的成员函数可以重载,可以使用默认参数。

3.类指针的用法与结构体指针用法相同。

4.类的成员可以是任意数据类型(类中枚举)。

5.可以为类的成员指定缺省值(C++11标准)。

6.类可以创建对象数组,就像结构体数组一样。

7.对象可以作为实参传递给函数,一般传引用。

8.可以用new动态创建对象,用delete释放对象。

9.在类的外部,一般不直接访问(读和写)对象的成员,而是用成员函数。

10.对象一般不用memset()清空成员变量,可以写一个专用于清空成员变量的成员函数。

11.对类和对象用sizeof运算符意义不大,一般不用。

12.用结构体描述纯粹的数据,用类描述对象。

13.在类的声明中定义的函数都将自动成为内联函数;在类的声明之外定义的函数如果使用了inline限定符,也是内联函数。

14.为了区分类的成员变量和成员函数的形参,把成员变量名加m_前缀或_后缀,如m_name或name_

15.类的分文件编写和函数分文件编写的思路和方法是一样的,一般情况下,把声明类的代码放在头文件中,把成员函数定义的代码放在源文件中。

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

class Point {
public:  
    int x;  
    int y;
    string name;
    enum{girl = 1, boy = 2};
    int sex;
    int times = 0;//记录递归的次数
    //9.在类的外部,一般不直接访问(读和写)对象的成员,而是用三个成员函数:清空,获取值,设置值
    void initdata()//专用于清空全部成员变量的成员函数
    {
        name.clear();
        x = 0;
    }
    
    int get_x()
    {
        return x;
    }
    
    void set_x(int x)
    {

    }

    void Show() 
    {
    if(times++ > 10) return;
    cout << x << " " <<  y << endl;
    if(sex == girl)
        {
            ;
        }
    }  

    void print();//这里要提前声明,不然会报错
};  

inline void Point::print() 
{  
    cout << x <<  y << endl;
}  

int main() 
{  
    Point p1;
    p1 = {10,20};  
    p1.Show(); // 调用成员函数
    p1.sex = p1.girl;  
    return 0;  
}

1-4 构造函数和析构函数

构造函数:在创建对象时,“自动”地进行初始化工作。
析构函数:在销毁对象前,“自动”地完成清理工作。

1.构造函数: 语法: 类名(){…} ·访问权限必须是public ·函数名必须与类名相同 ·没有返回值,也不写void ·可以有参数,可以重载,可以有默认参数 ·创建对象时会自动调用一次,不能手工调用。

2.析构函数:用于释放资源 语法:~类名(){…} ·访问权限必须是public。 ·函数名必须在类名前加~ ·没有返回值,不能重载 ·销毁对象前只会自动调用一次,但是可以手工调用,不过手工调用的场景非常少

demo程序

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

class Point{
public:  
    string m_name; //姓名属性
    int m_age;//年龄属性
    char m_memo[301];//备注
    int* m_ptr;

    Point()//构造函数,对三个成员变量进行初始化
    {
        initdata();
        //m_ptr = nullptr;
        cout << "调用了Point()构造函数。\n" << endl;
    }

    Point(string name)//构造函数,对三个成员变量进行初始化
    {
        initdata();
        cout << "调用了Point(name)构造函数。 \n" << endl;
    }

    Point(string name, int age)//构造函数,对三个成员变量进行初始化
    {
        initdata();
        cout << "调用了Point(name,age)构造函数。 \n" << endl;
    }

    void initdata()
    {
        m_name.clear(); m_age = 0; memset(m_memo,0,sizeof(m_memo));
    }
    ~Point()
    {
        //if(m_ptr != nullptr) delete m_ptr; //这里如果构造函数没有被调用,指针不会初始化为空
        cout << "调用了~Point()析构函数。\n" << endl;
    }

    void Show() 
    {
        cout << "姓名:" << m_name << ",年龄:" << m_age <<",备注:" << m_memo << endl;
    }  
};  
int main() 
{  
    //Point p1;//创建对象并自动调用没有参数的构造函数
    //Point p1("小红");//调用有name参数的构造函数,多个构造函数不能同时调用哦
    Point p1("小红",50);//调用有name,age参数的构造函数
    p1.Show(); //调用成员函数
    p1.~Point();
    return 0;  
}

析构函数的细节:

注意:
1.如果没有提供构造/析构函数,编译器将提供空实现的构造/析构函数
2.如果提供了构造/析构函数,编译器将不提供空实现的构造/析构函数
//输入输出都没有的就是空实现的构造/析构函数,如果自己定义了有参数的构造函数,那么在主函数调用时就不能调用空输入参数的函数了。
3.创建对象时,如果重载了构造函数,编译器根据实参匹配相应的构造函数

4.创建对象时不要在对象名后面加空的圆括号,编译器误认为时声明函数(没有构造函数、构造函数没有参数、构造函数的参数都有默认参数)
5.在构造函数名后面加括号和参数不是调用构造函数,是创建匿名对象(!!!很重要!!!)
6.接受一个参数的构造函数允许使用赋值语法将对象初始化为一个值(可能会导致问题,不推荐使用)

7.以下两行代码有本质的区别: Point p1 = Point("cy"20);//显示创建对象 Point p1;//创建对象 p1 = Point("cy"20);//创建匿名对象,然后给现有的对象赋值;一共创建了两个对象
8.用new/delete创建/销毁对象时,也会调用构造/析构函数
9.不建议在构造/析构函数中写太多的代码,可以调用成员函数

10.除了初始化,不建议让构造做太多工作(只能成功不会失败),因为没有返回值
11.C++11支持使用统一初始化列表
12.如果类的成员也是类,创建对象的时候,先构造成员类;销毁对象的时候,先析构成员类

int main() 
{  
    //Point* p1 = new Point();
    Point* p1 = new Point("cy",20);
    p1->Show(); // 调用成员函数
    delete p1;
    return 0;  
}

http://www.kler.cn/a/443213.html

相关文章:

  • python 数据分析之地图数据绘制
  • linux系统下硬盘无法读写,但是服务器上硬盘没有告警,确定故障硬盘的信息
  • GPT-SoVITS语音合成模型部署及使用
  • 从零开始,一步一步搭建Typescript+React+Redux项目——集成react-router和axios(三)
  • socket编程UDP-实现停等机制(接收确认、超时重传)
  • 第二部分:进阶主题 15 . 安全管理 --[MySQL轻松入门教程]
  • “TA”说|表数据备份还原:SQLark 百灵连接助力项目部署验收
  • SQL中表相关的操作
  • 增材制造(3D打印):原理、类型、领域、优势、瓶颈、方向
  • Oracle JDK需登录下载解决
  • [Unity]Unity跨平台开发之针对Android开发
  • Nmap初步学习
  • React中定义和使用类式组件
  • nano编辑器的使用
  • 4.metagpt中的软件公司智能体 (ProjectManager 角色)
  • CSS Backgrounds(背景)
  • 干掉运动模糊!Deblur4DGS:清晰的高质量视频动态重建
  • Mongodb 启用认证
  • 图变换器的再思考:谱注意力网络
  • Oracle Database 21c Express Edition数据库 和 Sqlplus客户端安装配置