您的位置:首页 > 科技 > 能源 > 发帖子有哪些app平台_企业形象vi设计公司_seo是什么的简称_抖音广告

发帖子有哪些app平台_企业形象vi设计公司_seo是什么的简称_抖音广告

2025/1/16 1:29:13 来源:https://blog.csdn.net/2301_77682837/article/details/145048918  浏览:    关键词:发帖子有哪些app平台_企业形象vi设计公司_seo是什么的简称_抖音广告
发帖子有哪些app平台_企业形象vi设计公司_seo是什么的简称_抖音广告

C++ Day4

  • 类中的特殊函数
    • 析构函数
    • 拷贝构造函数
    • 拷贝赋值函数
  • 友元
    • 友元函数
    • 友元类
      • 注意事项
  • 常成员
    • 常成员变量
    • 常成员函数
    • 常对象
    • mutable关键字
  • 运算符重载
    • 赋值类运算符重载
  • 作业

在这里插入图片描述

类中的特殊函数

析构函数

  1. 析构函数在对象的作用域结束时或者使用delete释放对象的空间时,系统自动调用,该函数用于对对象空间的释放工作以及后续的善后处理工作
  2. 析构函数没有参数,所以没有重载,一个类中只能有一个析构函数
  3. 如果没有手动定义的话,系统将会提供一个默认的析构函数,用于回收释放类对象的空间,如果手动定义了,那么系统将不会提供默认的析构函数了
  4. 手动定义析构函数的必要型:默认析构函数仅仅回收对象的内存空间,如果有一个成员指针指向了堆区空间,默认析构函数并不会释放其指向的堆区空间,将会导致内存泄露。此时需要手动定义析构函数,在函数体内手动释放成员指针指向的堆区空间
  5. 调用顺序:
    • 栈区空间:先申请的后释放,后申请的释放
    • 堆区空间:使用new时调用构造函数,使用delete时调用析构函数
  6. 定义格式
~类名 (){函数;
}

拷贝构造函数

  1. 使用一个类对象给另一个类对象进行初始化时,系统会自动调用拷贝构造函数
    例如:
    string s1(“hello”); //有参构造
    string s2(s1); //拷贝构造
    string s3 = s1; //拷贝构造
  2. 深浅拷贝问题
    如果类中没有手动定义拷贝构造函数,那么系统将会默认提供一个拷贝构造函数,来完成类对象之间的简单拷贝赋值
    倘若成员中含有指针时,指针将会指向同一片空间时。释放时将会出现多次释放同一片内存空间的问题,并且使用时可能产生静态
    此时应该手动定义拷贝构造函数,完成指针结构的拷贝,让两个指针指向不同的空间
  3. 定义格式
class Stu {
private:string name;int age;
public:Stu(const Stu &other):name(other.name), age(other.age){函数体;}
};

拷贝赋值函数

拷贝赋值函数也称为等号运算符重载函数:当使用一个同类对象给自己赋值是,系统自动调用
定义格式

例:类名为 Stu
Stu & operator= (counst Stu &other)
{函数体;
}

拷贝赋值函数同样涉及深浅拷贝问题,当成员中有指针指向堆区空间时,应该采用深拷贝的方式

友元

友元是类体对外开放相关权限的,被设置了友元的外界成员,可以直接访问该类里面的所有成员
友元分为友元函数和友元类

友元函数

  1. 将其他函数设为该类的友元函数,那么就允许这个函数访问该类的任何成员
  2. 友元函数分为全局友元函数,其他类中的友元函数
//全局友元函数
friend 函数头;
//其他类中友元函数
friend 类名::函数头;
//类成员函数作为友元函数时,要求该函数必须类内生命,类外定义

友元类

将一个类设置为当前类的友元类,那么那个类就可以访问当前类的所有成员
设置格式:

class 类名
{friend class 友元类名;
};

注意事项

  1. 上面的例子中,是友元类可以访问当前类的成员,友元类的设置是有方向性的
  2. 友元类实际上破坏了类的封装性,使访问权限变得模糊,不到万部分已一般不使用友元
  3. 友元不具有传递性
  4. 友元不具有继承性

常成员

const修饰类中的成员,例如常成员,常对象,常成员函数

常成员变量

  1. 用const修饰的成员变量即是常成员变量
  2. 常成员变量要求必须在构造函数的初始化列表中进行初始化

常成员函数

  1. 在常成员函数中,不允许更改成员变量的值,仅有读取功能
  2. 定义格式:返回值类型 函数名(形参列表) const {函数体;}
  3. 本质上常成员函数的const修饰的是隐形的参数this指针,由默认的类名 * const this固定指向的指针修改为const 类名 * const this指向与指向内容都固定的指针
  4. 同一个类中同名的常成员函数和成员函数构成重载关系,原因是二者的this指针不同

常对象

  1. 定义时使用const修饰的对象就是常对象
  2. 常对象,只能调用其内部的常成员函数,不能调用成员函数
  3. 普通对象,优先调用内部的成员函数,如果没有非常成员函数,才调用同名的常成员函数

mutable关键字

  1. 由关键字mutable修饰的成员变量,可以在常成员函数中被修改
  2. 常成员函数中,取消该成元变量的常属性

运算符重载

在C++中,所有对类对象操作的运算符,本质上都是函数调用来实现的
并允许程序员对这个函数进行重载,来实现对自己创建的类定义属于他的计算方式
定义格式

//此处#代指任意一种运算符,不同运算符需要的参数个数不同
返回值 operator# (参数列表) {函数体;}

赋值类运算符重载

//全局函数版本
类名 &operator= (类名 &L, const 类名&R)
{函数体;return L;
};//成员函数版本
类名 &operator= (const 类名&R)
{函数体;return *this;
};

作业

仿照string类,实现myString

//main.cpp
#include <iostream>
#include "mystring.h"using namespace std;int main()
{mystring s1(5,'a');s1.show();mystring s2 = s1;s2.show();mystring s3("hellobbbbb");cout << s3.at(2) << endl;s3 += s1;s3.show();cout << s3.get_len() << "  " << s3.get_size() << endl;return 0;
}
//mystring.h
#ifndef MYSTRING_H
#define MYSTRING_H#include <cstring>
#include <iostream>using namespace std;class mystring
{
private:char *str;int size;int len;
public://无参构造函数mystring();//有参构造函数1mystring(const char * s);//有参构造函数2mystring(int n, char ch);//拷贝构造函数mystring(mystring &other);//+=运算符重载mystring &operator+=(const mystring &other);//访问元素函数char &at(int i);//判空函数bool is_empty();//自动扩容函数void full();//获取C风格字符串char *get_c();//获取空间实际长度int get_size();//获取字符串的实际长度int get_len();//展示函数void show();
};#endif // MYSTRING_H
//mystring.cpp
#include "mystring.h"//无参构造函数
mystring::mystring() : str(new char[10]), size(10) , len(0)
{}//有参构造函数1
mystring::mystring(const char *s) : str(new char[strlen(s)]), size(strlen(s)), len(size)
{//参数列表:申请strlen大小的空间,size和len均设置为这个大小//将s中的内容拷贝到str中strcpy(str,s);
}mystring::mystring(int n, char ch) : str(new char[n+1]), size(n+1) ,len(size)
{//参数列表:申请n+1的空间,size和len均设置为这个大小//拼接字符串for(int i= 0; i < n; i++){str[i] = ch;}str[n+1] = 0;
}mystring::mystring(mystring &other): str(new char[other.get_len()]), size(other.get_len()) ,len(size)
{//参数列表:申请大小为other对象中str大小的空间,size和len均设置为这个值//拷贝other中字符串的值到str中strcpy(str, other.str);
}mystring &mystring::operator+=(const mystring &other)
{//求出拼接后的长度len += other.len;//判断一下是否需要扩容full();//拼接两个字符串strcat(str, other.str);return *this;
}char &mystring::at(int i)
{//判断访问位置是否合理if(i>=1 && i < len)return str[i-1];elsereturn str[-1];
}bool mystring::is_empty()
{//判断是否为空return len;
}void mystring::full()
{//判断修改后字符串的预计长度是否大于堆区空间的长度if(len > size){//创建一个临时指针,指向新申请大小为2*size的堆区空间char *temp = new char[2*size];//将老空间中的数据移动到新空间中memmove(temp, str, len);//释放老的堆区空间delete []str;//将str指针指向新的堆区空间str = temp;//扩容完毕,size变为两倍size = size*2;//temp指针闲置,置空temp = NULL;}}char *mystring::get_c()
{//返回字符指针,用于C风格操作return this->str;
}int mystring::get_size()
{//返回堆区空间大小return size;
}int mystring::get_len()
{//返回字符串的实际长度return len;
}void mystring::show()
{//输出字符串内容cout << str << endl;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com