c++面向对象--类的学习笔记

在学习类之前,相信很多人跟博主一样,已经学习过结构体。在 C++ 中,struct 和 class 的区别非常小,几乎只是默认访问权限的不同。默认访问权限/继承权限:

  • struct 的默认成员访问权限和默认继承方式都是 public。
  • class 的默认成员访问权限和默认继承方式都是 private。

学习完毕,完结撒花~~ :)

C++ 中的使用惯例:

struct:通常用于纯数据对象(POD, Plain Old Data),或者只有简单方法的数据结构。例如:点 Point、矩形 Rect、返回多个值的轻量级对象。
class:用于需要大量封装、继承和多态的完整对象。例如:FileStream, String, Animal 等。

第一个案例

写一个用户类,包含姓名,年龄,以及一个say函数,可以根据不同用户名称来组装欢迎语句。

#include <iostream>
using namespace std;

class User
{
public:
    string name;
    int year;
    void say(){
        cout << "Hello " << name << "!" << endl;
    }
};

int main()
{
    User zhao,qian;
    zhao.name="Zhao yi";
    qian.name="Qian er";
    zhao.say();
    qian.say();
}

构造函数

在 C++ 中,构造函数是一个特殊的方法,当创建类的对象时,它会自动被调用。要创建一个构造函数,请使用与类相同的名称,后跟括号 (),别看名字挺高大上,目测其实就是在一个类的实例被创建出来以后,做一些初始化的工作:

#include <iostream>
using namespace std;

class User
{
public:
    string name;
    int year;
    User(string x,int y){
        name=x;
        year=y;
        cout << "User " << name << "is created !" << endl;
    }
};

int main()
{
    User zhao("zhao yi" , 18),qian("qian er" , 16);
}

访问权限

上面的程序中出现了一个关键字 “public”。public 关键字是访问说明符。访问说明符定义如何访问类的成员(属性和方法)。在上面的例子中,成员是公共的 - 这意味着可以从代码外部访问和修改它们。

但是,如果我们希望成员是私有的,并对外部世界隐藏呢?在 C++ 中,存在三个访问说明符:

  • public - 成员可以从类外部访问
  • private - 成员不能从类外部访问(或查看)
  • protected - 成员不能从类外部访问,但可在继承的类中被访问。

在下面的例子中,我们演示了 public 和 private 成员之间的区别:

#include <iostream>
using namespace std;

class User {
    private:
        int year;
    public:
        string name;
        User(string x,int y){
            name=x;
            year=y;
            cout << name << " is " << y << " years old!" << endl;
        }
};

int main() {
    User zhao("zhao yi", 18);
    cout << zhao.year << endl;  //因为访问权限的问题,运行到这里就该报错了.
}

如果注释掉报错的那一行 cout 语句,程序会输出如下内容:

zhao yi is 18 years old!

也就是说,这个私有属性他自个儿还是能随便用,跟图馆内的不外借的文献一样,馆里随便看,想拿出去没门。
注意:默认情况下,如果您不指定访问说明符,类的所有成员都是私有的。

属性封装

封装的含义是确保“敏感”数据对用户隐藏。要实现这一点,必须将类变量/属性声明为私有(不能从类外部访问)。如果希望其他人读取或修改私有成员的值,可以提供公共的 get 和 set 方法。将类属性声明为私有被认为是一种良好的做法(尽可能多地使用)。封装可以确保更好地控制数据,因为您(或其他人)可以更改代码的一部分,而不会影响其他部分,从而增加了数据的安全性。

#include <iostream>
using namespace std;

class User {
    //默认private
    string name;
    int year;
    bool male;
    public:
    User(string n ,int y, bool m){
        name=n;
        year=y;
        male=m;
    }
    void getName(){
        cout << name << endl;
    }
    void setName(string n){
        name=n;
    }
};

int main(){
    User zhao("zhao yi",18,1);
    zhao.getName();
    zhao.setName("zhao yi yi");
    zhao.getName();
}

花式继承

就象动物可以分为爬行动物和两栖动物,两栖动物又可以分为两栖类动物主要包括无足目、无尾目和有尾目三个目。单个类并不能很好的表达或存储我们的数据,我们可以定义一个动物类,概括一些共有特征,再细分继承自动物类几个子类,在子类中扩展不同类别各自的属性,这样管理起来就清晰多了。子类也可以被继承,这个叫做多层继承;子类可以同时继承多个父类,这个叫多重继承。

#include <iostream>
using namespace std;

class Father{
public:
    void shout(){cout << "waoooooo" << endl;}
};

class Mother{
public:
    void cry(){cout << "55555555" << endl;}
};

class Son: public Father,public Mother{
public:
    void listen(){cout << "....enen" << endl;}
};

class Grandson: public Son{
public:
    void laugh(){cout << "hahahaha" << endl;}
};

int main(){
    Grandson xiaowang;
    xiaowang.shout();
    xiaowang.cry();
    xiaowang.listen();
    xiaowang.laugh();
}

继承方式

继承父类的时候也可以选择继承方式,但除了public外,其余两种方式都不常用,对于初学者,个人觉得直接先无脑public就可以了。

继承方式基类 public 成员变为基类 protected 成员变为基类 private 成员变为
public 继承派生类的 public 成员派生类的 protected 成员不可访问
protected 继承派生类的 protected 成员派生类的 protected 成员不可访问
private 继承派生类的 private 成员派生类的 private 成员不可访问

类的多态性

多态性意味着“多种形式”,它出现在我们通过继承相互关联的多个类中。继承允许我们从另一个类继承属性和方法。多态性使用这些方法来执行不同的任务。这使我们能够以不同的方式执行单个操作。例如,考虑一个名为 Animal 的基类,它有一个名为 AnimalSound() 的方法。动物的派生类可以是猪、猫、狗、鸟 - 并且它们也有自己的动物声音实现(猪叫声和猫喵叫声等):

#include <iostream>
using namespace std;

// 基类
class Animal {
  public:
    void animalSound() {
      cout << "动物发出声音 \n";
    }
};

// 派生类
class Pig : public Animal {
  public:
    void animalSound() {
      cout << "猪说:wee wee \n";
    }
};

// 派生类
class Dog : public Animal {
  public:
    void animalSound() {
      cout << "狗说:bow wow \n";
    }
};

int main() {
  Animal myAnimal;
  Pig myPig;
  Dog myDog;

  myAnimal.animalSound();
  myPig.animalSound();
  myDog.animalSound();
  return 0;
}

结合程序来看,继承自父类的属性或方法,可以在子类中重新定义并取代。

标签: c++

移动端可扫我直达哦~

推荐阅读

thumbnail 2025-09-05

P1088 [NOIP 2004 普及组] 火星人与康托展开

变进制数我们的目标是把全排列转化成一个变进制数,以方便我们进行加法。对于第 i 根手指,它有 n−i+1 种选择,根据位值原理,要想让每个数对应一个全排列,就要让这一位数是 n−i+1 进制的。那么,整个过程分为三步:将火星数变成变进...

少儿编程 c++

thumbnail 2025-09-04

用C++求全排列的几种方法

交换法交换法的优点:不需要额外的标记数组,空间复杂度更低,代码更简洁。需要注意的是,这个方式生成的全排列并非是字典序。#include <iostream> #include <algorithm> using...

少儿编程 c++

thumbnail 2025-08-30

关于 c++ 中的 unique() 函数

unique() 是C++标准库中一个非常实用的算法,用于去除相邻的重复元素。使用它之前需要先引入必须包含的头文件:#include<algorithm>基本语法#include <algorithm> // ...

少儿编程 c++

thumbnail 2025-08-30

lower_bound 为什么结果要减去数组名

lower_bound 结果减去数组名是为了将返回的迭代器(指针)转换为数组下标(索引)。lower_bound 返回的是一个迭代器(对于数组来说就是指针),指向找到的元素位置。int arr[] = {10, 20, 30, 40,...

少儿编程 c++

thumbnail 2025-08-25

c语言中的 fstream 与 freopen 区别

fstream(C++风格)和 freopen(C风格)都是用于文件输入/输出的工具,但它们在设计理念、用法和灵活性上有根本性的区别。核心概览 特性fstream (C++)freopen (C)所属语言标准C++C编程范式面向对象 ...

少儿编程 c++

thumbnail 2025-08-23

栈上数组和堆上数组

对比表格 特性栈上数组堆上数组内存位置栈内存堆内存声明方式int arr[10];int* arr = new int[10];生命周期所在作用域结束自动释放需要手动delete[]释放大小确定编译时确定(必须是常量)运行时确定(可以...

少儿编程 c++

thumbnail 2025-08-03

方格取数与传纸条-双人网格路径问题

24年在洛谷刷刷题,遇到过一个双人路径问题,P1004 [NOIP 2000 提高组] 方格取数,题解的4维数组对于博主这样一个菜鸟,实在难以理解,于是就搁置了。然而25年的时候又遇到了P1006 [NOIP 2008 提高组] 传纸...

少儿编程 c++

thumbnail 2025-07-16

二分查找无解为什么用 n+1

二分查找是一种在有序数组中查找特定元素的高效算法。它的基本思想是通过不断地将查找范围减半来快速定位目标元素。然而,在某些情况下,二分查找可能无法找到目标元素,这时就需要处理无解的情况。关于二分查找无解时使用 n+1 的原因,可以从以下...

少儿编程 c++

thumbnail 2025-07-16

关于后缀和的哨兵值

在二分查找结合后缀和(Prefix Sum / Suffix Sum)的问题中,哨兵值(Sentinel Value) 的作用是:处理边界情况(如所有元素都不满足条件时)。防止数组越界访问(如 sum[-1] 或 sum[n+1])。...

少儿编程 c++