网站管理与建设教程,广州澄网站建设公司,电脑建站软件,ajax 效果网站文章目录 类六个默认存在的成员函数构造函数#xff1a;析构函数#xff1a;拷贝构造函数:拷贝构造详解及细节#xff1a; 赋值运算符重载;取地址及const取地址操作符重载const修饰的含义#xff1a; 类六个默认存在的成员函数 构造函数 析构函数 拷贝构造函数 赋值运算… 文章目录 类六个默认存在的成员函数构造函数析构函数拷贝构造函数:拷贝构造详解及细节 赋值运算符重载;取地址及const取地址操作符重载const修饰的含义 类六个默认存在的成员函数 构造函数 析构函数 拷贝构造函数 赋值运算符重载 const成员函数 取地址及const取地址操作符重载 **一个类中不管存不存在成员变量和成员函数其内部都会默认生成以上六个成员函数 ** 构造函数 在一个类中如果没有自定义任何构造函数会自动生成一个默认的无参构造函数其没有任何功能。如果自己定义过一次构造函数则不会生成默认构造函数如果我们定义的不是无参构造方法以后就不可再使用无参构造了当然我们可以在定义出来一个无参构造函数。构造函数的格式 类名(参数列表){操作}…
构造函数还有个点就是当一个类包含另一个类的时候默认构造函数会默认调用被包含类的默认构造函数
析构函数
析构函数的作用和构造函数是相反的构造函数的作用是初始化类成员变量析构函数的作用就是当对象使用完了以后需要销毁的时候对内部的数据结构进行释放操作 格式 ~类名(){成员变量释放操作}
举个例子数组栈的C实现方法
//File:Stack.h
#includeiostream
using namespace std;
class Stack {
private:int* arr;int capcity;int top;bool CheckMemory();
public:Stack();~Stack();Stack(const Stack s);void PushBack(int n);int TopStack();void PopStack();bool isEmpty();
};//File:Stack.cpp
#includeStack.h
Stack::Stack() {capcity 4;top -1;int* temp (int*)malloc(sizeof(int) * capcity);if (temp nullptr) {perror(malloc fail);exit(-1);}arr temp;
}
Stack::~Stack(){free(arr);capcitytop 0;
}
Stack::Stack(const Stack s) {this-capcity s.capcity;this-top s.top;//deepin copyint* temp (int*)malloc(sizeof(int) * s.capcity);if (temp nullptr) {perror(copy fail);exit(-1);}this-arr temp;memcpy(arr, s.arr, sizeof(int) * capcity);
}
void Stack::PushBack(int n) {if (CheckMemory()) {//扩容int* temp(int*)realloc(arr, sizeof(int) * capcity * 2);if (temp nullptr) {perror(realloc fail);exit(-1);}arr temp;capcity * 2;}arr[top] n;
}
int Stack::TopStack() {return arr[top];
}
void Stack::PopStack() {top--;
}
bool Stack::CheckMemory() {return top capcity - 1;//ture is full,false isnt full
}
bool Stack::isEmpty(){return top -1;
}拷贝构造函数:
拷贝构造就有意思了在开始讲解之前我先用一段代码提问下大家
class demo {
private:int _a;
public:demo() {_a 1;cout demo() endl;}~demo(){cout ~demo() endl;}demo(const demo d) {_a d._a;cout demo(const demo d) endl;}
};
int main() {demo d1;demo d2d1;return 0;
}我想问下大家这个main函数里的d2d1 是进行的赋值操作还是进行的拷贝构造的操作
答案 显然这里进行的是拷贝复制这里我们将讲解下这是怎么回事以及为什么这里的拷贝构造函数为什么要传引用变量
拷贝构造详解及细节
1. 首先由C的规定我们在对一个并未初始化的类进行值传递的时候调用的就是拷贝构造函数而不是赋值函数这就很简单的解决了这里为什么调用的是拷贝构造函数的问题。
**2.第二个令人感到困惑的点就是拷贝构造函数我们传递的是引用数据类型首先也有个硬性规定这里传递的必须是指针另外这也是为了和第一点的特性做自洽处理因为我们如果值传递话会陷入一种无穷递归的情况每次传值都会进行一次拷贝调用每次拷贝调用也会触发值传递。这里没有任何方法可以控制因为这个递归他不会进入到函数每部除非栈空间耗尽不然他会一直递归 **
3. 拷贝构造在遇到成员变量也是一个类的时候也会调用被包含类的默认构造函数进行拷贝操作
4. 深浅拷贝问题其实我们大多数时候默认的拷贝构造只会完成浅拷贝这就会导致一个问题两个类的指针成员函数都指向一块堆空间这样在对象的生命周期结束时候进行销毁操作在析构函数里会对一片地址重复释放这样会直接引起程序的崩溃
赋值运算符重载;
其实赋值运算符重载的注意事项和拷贝构造函数的注意点最重要的就是深浅拷贝的问题不同的情况要灵活运用还有一个重要的就是赋值操作运算符重载只能在类的内部进行定义不能定义为全局函数其实这也很好理解因为如果我们不在类内定义的话编译器会自动生成一个默认的赋值函数这样会与全局的赋值运算符重载冲突。
取地址及const取地址操作符重载
其余两个默认成员函数其实并不怎么重要了这里我也就不做过多的赘述下边我需要讲一些重要的概念
demo* operator(){return this;
}const demo* operator()const
{
return this ;
}const修饰的含义
eg
const int a1;
int b1;
const int ca2;
int da2;请各位判断上边代码的对错情况
答案√×√×
这是为什么呢
主要是因为上述代码的右值都是临时变量而临时变量都具有常性而引用临时变量稍有不慎就会造成权限的放大大家自己想一下定义出来的a是存在栈上的还是在常量区。