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

C++基础精讲-04

文章目录

  • 1.初识面向对象
    • 1.1 面向对象概念
    • 1.2 对象和类的概念
    • 1.3 面向对象三大特性
  • 2.类的定义
    • 2.1 类的组成与基本格式
    • 2.2 访问修饰符
    • 2.3 c++对struct的增强
    • 2.4 c++中struct与class的对比
    • 2.5 成员函数的定义
  • 3. 对象的创建
    • 3.1 在栈上创建对象
    • 3.2 在静态区创建对象
    • 3.3 在堆区创建对象
  • 4.构造函数
  • 5.练手


1.初识面向对象

1.1 面向对象概念

面向对象是一种软件开发方法和编程范式,它将现实世界中的事物抽象为对象,以对象为核心来进行程序设计和开发

1.2 对象和类的概念

对象:是面向对象编程的核心概念,它是对现实世界中实体的抽象表示。每个对象都具有自己的属性(用于描述对象的特征)和方法(用于表示对象能够执行的操作)。例如,一个 “汽车” 对象,它可能有颜色、品牌、速度等属性,以及启动、加速、刹车等方法。
:是具有相同属性和方法的对象的抽象模板或蓝图。它定义了一类对象所共有的特征和行为。例如,“汽车” 类可以定义汽车普遍具有的属性和方法,而具体的某一辆汽车则是 “汽车” 类的一个实例对象。

由对象抽象出类由类实例化出对象

1.3 面向对象三大特性

1.封装
把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。类将成员变量和成员函数封装在类的内部,根据需要设置访问权限,通过成员函数管理内部状态。
2.继承
继承所表达的是类之间相关的关系,这种关系使得对象可以继承另外一类对象的特征和能力。
继承的作用:避免公用代码的重复开发,减少代码和数据冗余。
3.多态
多态性可以简单地概括为“一个接口,多种方法”,字面意思为多种形态。程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。

2.类的定义

2.1 类的组成与基本格式

1. 组成

  1. 数据,相当于现实世界中的属性,称为数据成员;

  2. 对数据的操作,相当于现实世界中的行为,称为成员函数

2.类的定义

class 类名{//类的定义
    //……
    void fun(){}  //成员函数
    int _a;          //数据成员
};


//类也可以先声明,后完成定义
class 类名;//类的声明

class类名{//类的定义
    //……
};

3.比如定义一个汽车类

class Car
{
	char _name[20];
	int _price;
};

2.2 访问修饰符

class中的所有的成员都拥有自己的访问权限,分别可以用三个访问修饰符进行修饰

1. public: //公有的访问权限,在类外可以通过对象直接访问公有成员

class Car
{
public:
	char _name[20];
	int _price;
};

void test(void)
{
	Car c;
	c.price=100   //可以
}

2.protected: //保护的访问权限,在本类中和派生类中可以访问,在类外不能通过对象直接访问
3. private: //私有的访问权限,在本类之外不能访问,比较敏感的数据设为private,类定义中可以访问。

class Car
{
private:
	char _name[20];
	int _price;
};

void test(void)
{
	Car c;
	c.price=100   //不可以
}

我们定义好一个Car的类,假设站在代工厂的视角,这个Car类拥有两个属性——品牌与价格;三个行为——设置品牌与设置价格和打印;

#include<iostream>
#include<cstring>
using std::endl;
using std::cout;

//类名每个单词首字母大写(建议)
class Car
{
public:
	void setName(const char* name)
	{
		strcpy(_name, name);
	}
	void setPrice(int price)
	{
		_price = price;
	}
	void print(void)
	{
		cout << "name=" << _name << endl;
		cout << "price=" << _price << endl;
	}

private:

	//属性名前加_与其他变量名区分
	char _name[20];
	int _price;
};

void test(void)
{
	Car c1; //定义Car类的对象;

	//调用成员
	c1.setName("大众");
	c1.setPrice(100000);
	c1.print();
}

int main(void)
{
	test();
	return 0;
}

在这里插入图片描述

2.3 c++对struct的增强

  1. c中定义结构体变量需要加上struct关键字,c++不需要。
  2. c中的结构体只能定义成员变量,不能定义成员函数。c++即可以定义成员变量,也可以定义成员函数。
#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
#include<cstring>
using std::endl;
using std::cout;

//类名每个单词首字母大写(建议)
struct Car
{
public:
	void setName(const char* name)
	{
		strcpy(_name, name);
	}
	void setPrice(int price)
	{
		_price = price;
	}
	void print(void)
	{
		cout << "name=" << _name << endl;
		cout << "price=" << _price << endl;
	}

private:

	//属性名前加_与其他变量名区分
	char _name[20];
	int _price;
};

void test(void)
{
	Car c1; //定义Car类的对象;

	//调用成员
	c1.setName("大众");
	c1.setPrice(100000);
	c1.print();
}

int main(void)
{
	test();
	return 0;
}

在这里插入图片描述

2.4 c++中struct与class的对比

C++ 对 struct 关键字扩展了其功能, 和 class 的功能⼏乎等价, 区别主要体现在默认访问权限上,struct 的成员默认访问权限是 public, class 的成员默认访问权限是 private

2.5 成员函数的定义

1.在类内实现

class Car
{
public:
	void setName(const char* name)
	{
		strcpy(_name, name);
	}
	void setPrice(int price)
	{
		_price = price;
	}
	void print(void)
	{
		cout << "name=" << _name << endl;
		cout << "price=" << _price << endl;
	}

private:

	//属性名前加_与其他变量名区分
	char _name[20];
	int _price;
};

2.在类外实现

//类名每个单词首字母大写(建议)
class Car
{
public:
	void setName(const char* name);
	void setPrice(int price);
	void print(void);

private:

	//属性名前加_与其他变量名区分
	char _name[20];
	int _price;
};

void Car:: setName(const char* name)
{
	strcpy(_name, name);
}
void Car::setPrice(int price)
{
	_price = price;
}
void Car::print(void)
{
	cout << "name=" << _name << endl;
	cout << "price=" << _price << endl;
}

3. 对象的创建

对象本质上就是⼀块内存,这块内存中存放的是创建这个对象的类描述的数据.

3.1 在栈上创建对象

在函数内部,⽤类定义⼀个变量, 这个变量就是栈上创建的对象;在函数调⽤结束的时候,栈上分配的内存会⾃动释放掉, 这个对象也就销毁掉了。

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
#include<cstring>
using std::endl;
using std::cout;

class Person
{
public:
	void setAge(int age)
	{
		_age = age;
	}
	void setName(const char* name)
	{
		strcpy(_name, name);
	}
	void print()
	{
		cout << "name=" << _name << endl;
		cout << "age=" << _age << endl;
	}
private:
	int _age;
	char _name[20];
};

void test(void)
{
	Person p1;
	p1.setName("张三");
	p1.setAge(20);
	p1.print();
}
int main(void)
{
	test();
	return 0;
}

在这里插入图片描述

3.2 在静态区创建对象

静态区对象的特点
1.静态区对象在程序启动时就被创建,直到程序结束才会被销毁。
2.静态区对象在整个程序生命周期内都存在,只会被初始化一次

#include<iostream>
#include<cstring>
using std::endl;
using std::cout;

class Person
{
public:
    void setAge(int age)
    {
        _age = age;
    }
 
    void setName(const char* name)
    {
        strcpy(_name, name);
    }
    
    void print()
    {
        cout << "name=" << _name << endl;
        cout << "age=" << _age << endl;
    }
private:
    int _age;
    char _name[20];
};

void test(void)
{
   
    static Person p1;
    p1.setName("张三");
    p1.setAge(20);
    p1.print();
}
int main(void)
{
    test();
    return 0;
}

3.3 在堆区创建对象

#include<iostream>
#include<cstring>
using std::endl;
using std::cout;

class Person
{
public:
    
    void setAge(int age)
    {
        _age = age;
    }
    
    void setName(const char* name)
    {
        strcpy(_name, name);
    }
   
    void print()
    {
        cout << "name=" << _name << endl;
        cout << "age=" << _age << endl;
    }
private:
    int _age;
    char _name[20];
};

void test(void)
{
    
    Person* p1 = new Person();
    p1->setName("张三");
    p1->setAge(20);
    p1->print();

    // 释放堆区内存,防止内存泄漏
    delete p1;
    p1 = nullptr;
}

int main(void)
{
    test();
    return 0;
}

4.构造函数

1.概念:构造函数是⼀个特殊的成员函数,名字和类名相同没有返回值,创建类类型对象时,⾃动调⽤,在对象的⽣命周期内只能调⽤⼀次,保证每个数据成员都有⼀个合适的初始值。
2.作用用来初始化数据成员的

#include<iostream>
#include<cstring>
using std::endl;
using std::cout;

class Person
{
public:
    
    void setAge(int age)
    {
        _age = age;
    }
    
    void setName(const char* name)
    {
        strcpy(_name, name);
    }
   
    void print()
    {
        cout << "name=" << _name << endl;
        cout << "age=" << _age << endl;
    }

    //无参构造函数
    Person()
    {
        cout << "我是无参构造函数" << endl;
        strcpy(_name, "张三");
        _age = 20;
    }
    //有参构造函数
    Person(const char*name,int age)
    {
        cout << "我是有参构造函数" << endl;
        strcpy(_name, name);
        _age = age;
    }
private:
    int _age;
    char _name[20];
};

void test(void)
{
    Person p1;
    p1.print();

    Person p2("李四", 20);
    p2.print();
}

int main(void)
{
    test();
    return 0;
}

在这里插入图片描述
3.总结

(1)函数名和类名⼀样
(2)没有返回值
(3)创建对象的时候,⾃动调⽤
(4)如果在设计⼀个类的时候,没有⼿动添加构造函数,编译器会根据需要⾃动添加添加⼀个默认的⽆参构造函数
(5)如果⾃⼰添加了构造函数,编译器就不会再添加默认构造函数
(6)构造函数不能⽤ const 修饰
(7)构造函数不能是虚函数
(8)构造函数可以重载

5.练手

1.编写⼀个类描述时间对象,可以设置⼩时、分钟、秒,也可以输出设置的时间

#include<iostream>
#include<cstring>
using std::endl;
using std::cout;

class Time {

public:
    void setH(int h)
    {
        _h = h;
    }
    void setM(int m)
    {
        _m = m;
    }
    void setS(int s)
    {
        _s = s;
    }

    void print()
    {
        cout << "时间:" << _h << "点" << _m << "分" << _s << "秒" << endl;
    }
    //无参构造
    Time()
    {
        _h = 0;
        _m = 0;
        _s = 0;
    }
private:
    int _h;   //时
    int _m;   //分
    int _s;   //秒
};

void test(void)
{
    Time t;
    t.print(); //打印出构造函数里的默认值

    t.setH(20);
    t.setM(30);
    t.setS(50);
    t.print();
}

int main(void)
{
    test();
    return 0;
}

2.请设计一个Person类,Person类具有name和age属性,提供初始化函数,并提供对name和age的读写函数(set,read),但必须确保age的赋值在有效范围内(0-100),超出有效范围,则拒绝赋值,并提供方法输出姓名和年龄。


#include <iostream>
#include <string>
using std::endl;
using std::cout;
using std::string;
using std::cin;

class Person {
public:
    // 确保age的有效赋值(0 - 100)
    bool c_Age(int age) {
        if (age < 0 || age > 100) {
            cout << "年龄错误,请输入 0 到 100 之间的年龄。" << endl;
            return false;
        }
        return true;
    }

    // 有参构造函数
    Person(int age, string name) {
        if (c_Age(age)) {
            _age = age;
            _name = name;
        }
        else {
            _age = 0;
            _name = " ";
        }
    }

    // 对年龄和姓名的写权限
    bool setAge(int age) {
        if (c_Age(age)) {
            _age = age;
            return true;
        }
        return false;
    }

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

    // 对年龄和姓名的读权限
    int read_Age() const {
        return _age;
    }

    string read_Name() const {
        return _name;
    }

    // 输出姓名和年龄
    void print() const {
        cout << "name=" << _name << "; ";
        cout << "age=" << _age << endl;
    }

private:
    int _age;
    string _name;
};

void test() {
    Person p(0, "张三");   // 利用有参构造函数初始化;
    cout << "打印默认值:";
    p.print();

    cout << "设置姓名:";
    string name;
    cin >> name;
    p.setName(name);

    cout << "设置年龄: ";
    int age;
    cin >> age;
    while (!p.setAge(age)) {
        cout << "请重新输入年龄: ";
        cin >> age;
    }

    // 读权限
    cout << "读取到的数据:";
    cout << p.read_Age() << "; " << p.read_Name() << endl;
    cout << "打印:" << endl;
    p.print();
}

int main() {
    test();
    return 0;
}

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

相关文章:

  • 对称加密与非对称加密与消息摘要算法保证https的数据交互的完整性和保密性
  • <C#>在 C# .NET 6 中,使用IWebHostEnvironment获取Web应用程序的运行信息。
  • 谷歌闭源Android后的生态变局与数据库国产替代的必要性——以金仓数据库为例
  • 出口商品贸易方式企业性质总值数据库
  • ReentrantLock 实现公平锁和非公平锁的原理!
  • swift菜鸟教程6-10(运算符,条件,循环,字符串,字符)
  • 2025年第十八届“认证杯”数学中国数学建模网络挑战赛【BC题】完整版+代码+结果
  • 深入剖析观察者模式:原理、实践与 Spring 源码解读
  • 深度学习总结(8)
  • CSS高级技巧
  • 使用治疗前MR图像预测脑膜瘤Ki-67的多模态深度学习模型
  • 【Qt】QxOrm:下载、安装、使用
  • 界面控件DevExpress WinForms v25.1新功能预览 - 聚焦用户体验升级
  • 如何应对“最后时刻任务堆积”(鼓包现象)
  • 《Vue Router实战教程》5.嵌套路由
  • 二叉树的应用
  • Dubbo、HTTP、RMI之间的区别
  • 递归?递推?
  • Asp.NET Core WebApi 创建带鉴权机制的Api
  • 蓝桥杯 — — 接龙数列
  • 1号网站建设 高端网站建设/怎么做网站排名
  • 学校网站建设及使用档案/2023重大新闻事件10条
  • 都匀网站建设/制作网站推广
  • 网站做任务赚qb/网络推广的概念
  • 温州云海和联欣哪个做网站比较好/企业策划
  • 网站设计学习/前端seo是什么意思