IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 类和对象 -> 正文阅读

[C++知识库]C++ 类和对象

1. 访问权限

  • public :公共权限
  • protected:保护权限,子类可以访问
  • private:私有权限,仅仅自己可以访问

2. struct 和class区别

  • 在C++中,struct和class唯一的区别在于默认的访问权限不同
  • struct默认权限为公共
  • class默认权限为私有

3. 属性成员私有化

  • 优点1:将所有成员属性设置为私有,可以自己控制读写权限
  • 优点2:对于写权限,我们可以检测数据的有效性
class Person
{
public:
    void setName(string name)
    {
        _name = name;
    }
    
    string getName()
    {
        return _name;
    }
    
    int getAge()
    {
        return _age;
    }
    
    void setLover(string lover)
    {
        _lover = lover;
    }
    
private:
    string _name; // 可读 可写
    int _age; // 可读
    string _lover; // 可写
};

4. 把.hpp(或称为.h)文件和.cpp文件抽出来

创建Person类

    1. 创建.hpp文件
#ifndef hanshu_hpp
#define hanshu_hpp
#pragma once
using namespace std;
#include <stdio.h>
#include <iostream>

class Person
{
public:
    void setName(string name);
    string getName();
    
    int getAge();
    void setLover(string lover);
    
private:
    string _name; // 可读 可写
    int _age; // 可读
    string _lover; // 可写
};
#endif /* hanshu_hpp */
  • 2 创建.cpp文件
#include "hanshu.hpp"
#include <iostream>
using namespace std;

void Person::setName(string name)
{
    _name = name;
}

string Person::getName()
{
    return _name;
}

int Person::getAge()
{
    return _age;
}

void Person::setLover(string lover)
{
    _lover = lover;
}

5. 对象的初始化和清理

  • 构造函数和析构函数
class Cat
{
public:
    //一、构造函数
    /**
     1. 没有返回值, 不用写void
     2. 函数名 与类名相同
     3. 构造函数可以有参数,可以发生重载
     4.创建对象的时候,构造函数会被自动调用,而且只调用一次
     */
    Cat()
    {
        cout << "cat 构造函数调用" << endl;
    }
    
    //二、析构函数
    /**
     1. 没有返回值 不写void
     2.函数名和类名相同 在名称前加~
     3.析构函数不可以有参数,不可以发生重载
     4.对象在销毁前,会被自动调用,而且只调用一次
     */
    ~Cat()
    {
        cout << "cat 析构函数调用" << endl;
    }
};

6. 有参、无参、拷贝 – 构造函数

class Pig
{
public:
    Pig()
    {
        cout << "pig 无参构造函数" << endl;
    }
    
    Pig(int a)
    {
        _age = a;
        cout << "pig 有参构造函数" << endl;
    }
    
    Pig(const Pig &p)
    {
        _age = p._age;
        cout << "pig 拷贝构造函数" << endl;
    }
    
    ~Pig()
    {
        cout << "pig 析构函数" << endl;
    }
    
    int _age;
};

int main(int argc, const char * argv[]) {
    // 一、括号法
//    Pig p;
//    Pig p2(10);
//    Pig p3(p);
    
//    Pig p(); // 不要这样写
    // 注意事项1:
    // 1. 调用默认构造函数时候,不要加(),因为编译器会误认为是一个函数的声明
    
    // 二、显示法
    Pig p1;
    Pig p2 = Pig(10);
    Pig p3 = Pig(p2);
      
    Pig(10); // 匿名对象 特点:当前行执行结束后,系统会立即回收匿名对象
    // 注意事项2:
    // 2. 不要利用拷贝构造函数 初始化匿名对象
//    Pig(p2); // 报错:Redefinition of 'p2' 因为 Pig(p2) 会被编译器转换为 Pig p2; 重复定义了对象
    
    // 三、隐式转换法
    Pig p4 = 10; // 会被转换为 Pig p4 = Pig(10);
    Pig p5 = p4; // 拷贝构造
    
    return 0;
}

7. 拷贝构造函数调用时机

  • C++ 中拷贝构造函数调用时机通常有三种情况
    1. 使用一个已经创建完毕的对象来初始化一个新对象
    1. 值传递的方式给函数参数传值
    1. 以值方式返回局部对象
int main(int argc, const char * argv[]) {
//    1. 使用一个已经创建完毕的对象来初始化一个新对象
//    Pig p1 = Pig(10);
//    Pig p2 = p1;
    /** 打印内容
     pig 无参构造函数
     pig 拷贝构造函数
     pig 析构函数
     pig 析构函数
     */
    
    //2. 值传递的方式给函数参数传值
//    Pig p3;
//    eat(p3); // 值传递,内部会拷贝一份对象,所以会调用拷贝构造函数
    /** 打印内容
     pig 无参构造函数
     pig 拷贝构造函数
     pig 析构函数
     pig 析构函数
     */
    
    // 3. 以值方式返回局部对象
    Pig p = getPig();
    cout << "函数调用的地址:" << (int*)&p << endl;
    /** 打印内容(在Mac平台下,用xcode打印如下,但是原来教学视频在Windows下,打印的地址却不一样,会调用拷贝构造函数,所以严格意义来说,这个应该和平台有关系)
     pig 无参构造函数
     函数创建的地址:0x7ff7bfeff2d8
     函数调用的地址:0x7ff7bfeff2d8
     pig 析构函数
     */
    return 0;
}

8. 构造函数调用规则

一、 默认情况下,C++编译器至少给一个类添加3个函数

    1. 默认构造函数(无参,函数体为空)
    1. 默认析构函数(无参,函数体为空)
    1. 默认拷贝构造函数,对属性进行值拷贝

二、构造函数调用规则如下:

    1. 如果用户定义有参构造函数,C++不再提供默认无参构造,但是会提供默认拷贝构造
    1. 如果用户定义拷贝构造函数,C++不会再提供其他构造函数

9.深拷贝和浅拷贝

概念:

  • 深拷贝:重新开辟一块内存,指向新的地址
  • 浅拷贝:新的指针,指向原来的内存地址
class Horse
{
public:
    Horse()
    {
        cout << "Horse 无参构造函数" << endl;
    }
    
    Horse(int age, int height)
    {
        _age = age;
        _height = new int(height);
        cout << "Horse 有参构造函数" << endl;
    }
    
    Horse(Horse &h)
    {
        _age = h._age;
        _height = new int(*h._height); // 通过new,开辟一块新的内存空间,深拷贝
//        _height = h._height; // 指针的值引用,浅拷贝
        cout << "Horse 拷贝构造函数" << endl;
    }
    
    ~Horse()
    {
        delete _height; // 浅拷贝的时候,第二个对象是否这个指针引用的值的时候,会释放失败,崩溃,深拷贝则不会
        _height = NULL;
        cout << "Horse 析构函数" << endl;
    }
    
    int _age;
    int *_height;
};

int main(int argc, const char * argv[]) {
    
    Horse h1(3,5);
    Horse h2(h1);
    cout << "h1的年龄:" << h1._age << ",  h1的身高:" << *h1._height << endl;
    cout << "h2的年龄:" << h2._age << ",  h2的身高:" << *h2._height << endl;
    return 0;
}

10. 初始化列表方式

class Fish
{
    
public:
    // 1.传统初始化方式
//    Fish(int a, int b, int c)
//    {
//        _a = a;
//        _b = b;
//        _c = c;
//    }
    
    // 2. 初始化列表方式初始化
    Fish(int a, int b, int c) : _a(a), _b(b), _c(c)
    {
        // do else things...
    }
    
private:
    int _a;
    int _b;
    int _c;
};

11. 静态成员

  • 静态成员就是在成员变量和成员函数前加上static关键字,称为静态成员
  • 分类
    • 静态成员变量
      • 所有对象共享同一份数据
      • 在编译阶段分配内存
      • 类内声明,类外初始化
    • 静态成语函数
      • 所有对象共享同一个函数
      • 静态成员函数只能访问静态成员变量
class Bird
{
public:
    static int _age;
    static void test()
    {
        _height = 30;
//        _length = 1; // 无法访问非静态成员变量,会报错
        cout << "static void test 调用" << endl;
    }
private:
    static int _height;
    int _length;
    static void test2()
    {
        cout << "类外无法访问私有静态成员函数" << endl;
    }
};

int Bird::_age = 10; // 类内声明,类外初始化

int main(int argc, const char * argv[]) {
    Bird b1;
    cout << "b1的age: " << b1._age << endl;
    
    Bird b2;
    b2._age = 20;
    cout << "b1的age: " << b1._age << endl;
    
    // 通过类访问静态成员变量
    cout << "通过类访问静态成员变量: " << Bird::_age << endl;
//    cout << "通过类访问静态成员变量: " << Bird::_height << endl; // 访问不了私有静态成员变量
    
    // 静态成员函数访问的两种方式
    b1.test(); // 1. 通过对象访问
    Bird::test(); // 2. 通过类访问
    
    
    return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 18:45:50  更:2022-08-19 18:48:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/12 23:58:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码