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

《C++程序设计》笔记p4 - 指南

《C++程序设计》笔记p4 - 指南

C++ 类中的四个默认成员函数

  1. 构造函数
  2. 拷贝构造函数
  3. 析构函数
  4. 赋值运算符重载
class 类名{
public:
类名(void);
类名(const 类名 &);
~类名(void);
类名 & operator =(const 类名 &);
};

赋值运算符重载:

作用:代替默认的赋值运算符成员函数来控制对象复制的过程,从而避免复制过程中的浅拷贝。

调用时机: 在对象已经创建,并在后续运行阶段对其值进行修改时调用。

语法:

class 类名{
类名 & operator = (const 类名 & src) {
...
return *this;
}
};

示例:

#include
#include
#include
using namespace std;
// 定义一个MyString类,使用动态数组来存储字符信息
class MyString {
public:
// 将字符串初始化成 n个内容为 c的字符
MyString(char c, int n) {
cout copy(src);
// 释放自己原有的内存
// free(data);
// int str_len = strlen(src.data);
// data = (char*)malloc(str_len+1);
// strcpy(data, src.data);
return *this;
}
const char * c_str(void) {
return data;
}
private:
char * data;
public:
// 要求不能有内存泄漏
void copy(const char * content) {
// 释放自己原有的内存
free(data);
int str_len = strlen(content);
data = (char*)malloc(str_len+1);
strcpy(data, content);
}
inline void copy(const MyString & src){
// 释放自己原有的内存
free(data);
int str_len = strlen(src.data);
data = (char*)malloc(str_len+1);
strcpy(data, src.data);
}
};
int main(int argc, char * argv[]) {
MyString s1 = "zhangsan";
MyString s2 = s1;
MyString s3;
// MyString s2;
// s2.copy(s1);
//调用MyString& MyString::operator=(const MyString&);
s3 = s2 = s1;
cout << "s1:" << s1.c_str() << endl; // zhangsan
cout << "s2:" << s2.c_str() << endl; // zhangsan
cout << "s3:" << s3.c_str() << endl; // zhangsan
s2.copy("lisi");
cout << "s2:" << s2.c_str() << endl; // lisi
cout << "程序结束!" << endl;
return 0;
}

构造函数调用的时机

  1. 栈、堆以及全局对象的对象创建。
  2. 函数参数传值(传引用和传址不会创建新对象)
  3. 函数返回值(非引用和传址是不会创建新对象)

示例:

#include
#include
#include
using namespace std;
class MyString2 {
public:
MyString2(const string & s="") {
cout << "MyString2(" << s << ")" << endl;
data = s;
}
// 拷贝构造函数,对指针执向的内容进行深度复制
MyString2(const MyString2 & src) {
cout << "拷贝构造MyString2()" << src.data << endl;
data = src.data;
}
// 析构函数
~MyString2(){
cout <<"~MyString2(" << data << ")" << endl;
}
MyString2& operator=(const MyString2 &src) {
cout << "operator = 被调用:"<< data << endl;
data = src.data;
return *this;
}
private:
string data;
};
MyString2 &myfun(MyString2 & arg1) {
return arg1;
}
int main(int argc, char * argv[]) {
MyString2 s1("A1");
// MyString2 s2;
MyString2 &s2 = myfun(s1);
cout << "程序结束!" << endl;
return 0;
}

类的声明方式

  1. 仅声明类
  2. 声明类,同时声明成员变量和成员函数.

仅声明类

class 类名;

声明类,同时声明成员变量和成员函数。

class 类名 {
public:
类名(形式参数列表);
返回类型 成员函数名(形式参数列表);
...
private:
变量类型1 成员变量1;
变量类型2 成员变量2;
...
};

友元声明

友元声明是指让声明的一个函数、类或成员函数可以访问该类的私有和保护成员。

作用:让全局函数、其他类或其他类的成员函数可以访问该类的私有和保护成员。

关键字 friend

友元声明的分类

  1. 友元函数
  2. 友元成员函数
  3. 友元类

语法:

class 类名 {
// 友元函数的声明语法
friend 返回类型 友元函数名(形式参数列表);
// 友元成员函数的声明语法
friend 返回类型 其他类::类名友元函数名(形式参数列表);
// 友元类的声明语法
friend class 其他类;
};

示例代码

#include
using namespace std;
class Children; // 类声明
class Parent{
public:
Parent(const string & n, int a)
: name(n),age(a),money(0){}
void work(int m);
void showInfo(void);
void giveMoneyTo(Children & c, int m); // 给孩子钱
private:
string name;
int age;
int money;
// 声明show_money函数可以访问本类的所有成员
friend void show_money(const Parent &);
friend class Children;
};
class Children {
public:
Children(const string & n, int a)
: name(n),age(a),money(0){}
void showInfo(void);
void borrowTo(Parent & p, int m);
private:
string name;
int age;
int money;
// 仅声明Parent类的giveMoneyTo函数可以访问本类的所有成员
friend void Parent::giveMoneyTo(Children & c, int m);
};
void Parent::work(int m) {
money += m;
}
void Parent::showInfo(void) {
cout  this->money) {
cout money -= m;
c.money += m;
}
void Children::borrowTo(Parent & p, int m) {
if (m > this->money) {
cout money -= m;
p.money += m;
}
// 全局函数,用来打印家长的钱数;
void show_money(const Parent & p) {
cout << p.age << "岁的" << p.name << "有钱"
<< p.money << "元" << endl;
}
int main(int argc, char * argv[]) {
Parent p("老张", 31);
Children c("小张", 12);
p.work(1000);
show_money(p);
p.giveMoneyTo(c, 700);
p.showInfo();
c.showInfo();
c.borrowTo(p, 200);
p.showInfo();
c.showInfo();
return 0;
}

常成员函数

作用:声明一个成员函数为常成员函数,常成员函数在修改该类成员变量时将会报错(在编译阶段报错),且不能调用常成员函数

语法:

class 类名{
返回类型 成员函数名(形式参数列表) const {...}
};

示例代码

#include
using namespace std;
class Parent{
public:
Parent(const string & n, int a)
: name(n),age(a),money(0){}
void work(int m);
void showInfo(void) const;
private:
string name;
int age;
int money;
};
void Parent::work(int m) {
money += m;
}
void Parent::showInfo(void) const {
cout work(100); // 报错
}
int main(int argc, char * argv[]) {
Parent p("老张", 31);
p.work(1000);
p.showInfo();
return 0;
}

静态成员函数和静态成员变量

静态成员变量

是类内的变量,他的作用域属于类。

声明的语法:

class 类名{
访问说明符:
static 变量类型 变量名;
};

初始化的语法

变量类型 类名::变量名[ = 初始值];

静态成员变量的使用方法

类名::变量名
对象名.变量名

示例:

记录一个类创建对象的个数;

#include
#include
#include
using namespace std;
class Human {
public:
static int total_count;
Human(const string & n) : name(n){
cout << "Human(" << name << ")\n";
total_count++;
}
~Human(){
cout << "~Human(" << name << ")\n";
total_count--;
}
private:
string name;
};
int Human::total_count = 0;
int main(int argc, char * argv[]) {
Human zhang3("张三");
do {
Human li3("李四");
} while(0);
// 程序运行到此处能否指导此时创建了几个Human对象?
cout << "人口总数" << Human::total_count << endl;
cout << "人口总数" << zhang3.total_count << endl;
cout << "程序结束!" << endl;
return 0;
}

静态成员函数

是类的函数,他只能访问类的静态成员变量,不能访问对象的成员变量。

说明:

  • 静态成员函数 没有this指针,不能访问对象的成员变量。
  • 静态成员函数的作用域属于据类。

静态成员函数 的定于的语法

class 类名{
public:
// 类内声明,类内实现。
static 返回类型 函数名1(形式参数列表) {};
// 类内声明,类外实现。
static 返回类型 函数名2(形式参数列表);
}

类外实现的语法

返回类型 类名::函数名2(形式参数列表) { ... }

调用方法

类名::函数名2(实际参数列表)
对象.函数名2(实际参数列表)

面相对象编程语言的特征

  • 封装
  • 继承
  • 多态

封装

封装是指隐藏对象的实现细节,让使用者不关心这些细节。从而保证数据的安全性。

使用者只需要调用简单的接口的即可使用。

C++ 通过访问说明符实现封装。

访问说明符

  • public
  • protected
  • private
访问说明符成员函数子类成员函数其他
public可以访问可以访问可以访问
protected可以访问可以访问无法访问
private可以访问无法访问无法访问

继承

继承是允许一个类(子类或派生类)基于另外一个类(父类或基类)创建,并继承基类的成员变量和成员函数。

继承的作用:

  • 将公有部分放入基类,实现代码共享。
  • 子类可以在原有的基础上添加新的功能。

继承的语法:

class 子类名:继承方式 基类名 {
...
};

继承方式

  • 共有继承 public
  • 保护继承 protected
  • 私有继承 private

继承的内存结构

显式调用父类的构造函数的语法

class 子类名:继承方式 基类名 {
public:
子类名(形参列表): 基类名(实参),成员变量1(实参),成员变量2(实参){...}
};

示例:

#include
#include
#include
using namespace std;
// 点类(描述一个点的位置,面积,周长等信息
class Point {
public:
Point(int ax=0, int ay=0):x(ax), y(ay) {
cout << "Point(" << x << "," << y << ")\n";
}
void info(void) {
cout << "点(" << x << "," << y << ")\n";
}
void moveTo(int new_x, int new_y) {
x = new_x; y = new_y;
}
float getArea(void) {
return 0;
}
float getLength(void) {
return 0;
}
public:
int x;
int y;
};
// 定义一个圆的类(位置和半径)
class Circle : public Point {
public:
Circle(int ax, int ay, int radius)
: Point(ax, ay), r(radius) {
//  x = ax; y = ay; r = radius;
cout << "Circle(" << x << "," << y << "," << r << ")\n";
}
// void info(void) {
//     cout << "圆(" << x << "," << y << "," << r << ")\n";
// }
// float getArea(void) {
//     return 0;
// }
// float getLength(void) {
//     return 0;
// }
public:
int r; // 半径
};
int main(int argc, char * argv[]) {
Point p1(3, 5);
Circle c1(4, 6, 10);
cout << "sizeof(p1)" << sizeof(p1) << endl;
cout << "sizeof(c1)" << sizeof(c1) << endl;
c1.info();
p1.info();
p1.moveTo(100, 105);
// 子类对象不存在moveTo,则调用父类的方法
c1.moveTo(200, 210);
p1.info();
c1.info();
cout << "程序结束!" << endl;
return 0;
}

访问权限

基类访问权限继承方式本类访问权限
publicpublicpublic
protectedpublicprotected
privatepublic不可访问
publicprotectedprotected
protectedprotectedprotected
privateprotected不可访问
publicprivateprivate
protectedprivateprivate
privateprivate不可访问
http://www.hskmm.com/?act=detail&tid=19061

相关文章:

  • 电脑显示器黑屏(闪烁:隔几秒中黑一两秒),向日葵远程正常——DeepSeek问答
  • 实用指南:iOS 26 兼容测试实战,机型兼容、SwiftUI 兼容性改动
  • 大中午记梦
  • 概率/期望 $dp$
  • 9.21~9.27 周总结
  • Jetbrains 全家桶激活码激活
  • 【深度学习计算机视觉】07:单发多框检测(SSD) - 指南
  • MZOI 2025.9.27
  • 原码 反码 补码
  • Spring Framework 远程命令执行漏洞
  • 配置本地环境以管理Git多账户SSH连接
  • Pod、 PVC 、PV的
  • 百度网盘ByPy使用配置指南
  • 完整教程:AI 术语通俗词典:Diffusion Models(扩散模型)
  • pip安装依赖包报错内容为User defined options,Native files 如何解决
  • edu 107 E(概率期望, dp)
  • 2025 年空气离合器生产厂家推荐榜:电网冲击缓解技术与可靠性测评,单片空气离合器,多片空气离合器,空气离合器摩擦片,空气离合器密封件公司推荐
  • Spring MVC的双向数据绑定
  • 抽象化编程(Abstraction in Programming)
  • 9月27日
  • 配置RedisTemplate序列化机制
  • 优化器(Optimizer)
  • 2025 年气动离合器品牌推荐排行榜发布,聚焦博得 PLC 控制技术与降本优势,常开式气动离合器,多片式气动离合器,气动离合器电磁阀,气动离合器气缸,单片式气动离合器工厂推荐
  • Kubernetes Ingress与OpenShift Router的比较分析
  • Kubernetes日志管理:使用Loki进行日志采集
  • PySimpleGUI 4.60.5完整控件列表
  • 2025黄鹤杯线上wp
  • !!!
  • Dropout
  • 经典排序算法深度解析 - 实践