一.析构函数:对象销毁自动调用的函数,它可以显示使用
~类名(void)
注意:
1.当存在移动构造时,需要在释放空间之前判断是否是临时变量,如果是临时变量则不需要释放
2.使用析构显示调用时需要注意重复释放的问题
#include
#include
using namespace std;
class String{
public:
//普通构造
String(const char*p)
{
/*
if(nullptr == p)
异常处理
*/
cout<<"normal"< len)
{
//p大于原来的空间,应该重新开辟一个空间
delete []addr;
addr = new char[strlen(p)+1];
strcpy(addr, p);
len = strlen(p);
}
else
{
strcpy(addr, p);
len = strlen(p);
}
}
void append(const char* p)
{
char buf[len+1]; //存储原始数据
strcpy(buf, addr);
delete []addr;
addr = new char[len+strlen(p)+1];
strcpy(addr, buf);
strcat(addr, p);
len += strlen(p);
}
private:
char *addr;
int len;
};
void test()
{
char buf[100] = "hello";
String A = buf;
}
int main()
{
test();
while(1);
}
二.static
1.修饰变量
{
1.修饰全局变量,生命周期不变,作用域被限制在本文件
2.修饰局部变量,延长生命周期到程序结束,作用域不变
}
2.修饰函数
{
1.修饰函数,生命周期不变,作用域限制在本文件
}
3.修饰类相关
[
特点:静态成员,不和具体对象关联,没有对象生成静态成员也存在
静态成员不属于类,多个对象公用一个静态成员
静态成员使用之前必须初始化,类型+类名::变量名=n;
联系:利用static变量,计算某个类对象个数
修饰共有成员
#include
using namespace std;
class demo{
public:
void setval(int n)
{
demo::a = n;
}
int getval()
{
return demo::a;
}
static int a;
//int b;
};
int demo::a = 1; //static init
int main()
{
// demo b;
demo::a=100;
cout<
修饰私有成员
#include
using namespace std;
class demo{
public:
void setval(int n)
{
demo::a = n;
}
int getval()
{
return demo::a;
}
private:
static int a;
//int b;
};
int demo::a = 1; //static init
int main()
{
demo b, c;
//因为静态变量只有一份,所以b改成10, c打印依然是10
cout<
1.修饰成员变量的情况
2.修饰成员函数
{
(1).不能访问非静态的类成员
(2).非静态的类成员可以访问静态成员
(3).静态成员没有this指针
#include
using namespace std;
class demo{
public:
demo()
{
a++;
}
demo(demo&obj)
{
a++;
}
demo(demo &&obj)
{
a++;
}
static int getval()
{
return a;
}
void func()
{
getval();
}
~demo()
{
a--;
}
private:
static int a;
int b;
};
int demo::a = 0;
void func()
{
//demo A,B,C;
cout<
关于this指针
{
thie指针
#include
class demo{
public:
//形参和成员变量同名
void setval(int a)
{
this->a=a;
}
//返回对象指针
demo *func()
{
return this;
}
//返回对象
demo &func()
{
return *this;
}
private:
int a;
}
int main()
{
demo A;
}
}
}
]
三.const
1.const修饰类的成员变量:
(1).修饰的变量不能被更改,const修饰的变量需要初始化
(2).const修饰的成员变量,必须使用初始化列表进行初始化
(3).非const成员函数可以访问const修饰的变量
初始化列表
{
1.可以初始化const修饰的变量,也可以初始化非const修饰的变量
}
#include
using namespace std;
class demo{
// 非const成员函数可以访问,const成员变量
public:
demo(int n, char c , int *p):
a(n),ch(c),b{p[0], p[1], p[2]} //初始化列表格式,分别对int,char,数组,进行的初始化
{
}
void printf_demo()
{
cout<
2.const修饰函数
格式: 返回值 函数名()const
1.const修饰的函数可以访问const成员
2.const修饰的函数可以访问非const成员
重点3.函数内部不能出现修改变成员量值的逻辑出现!
可以看出其实const的作用并不在于访问,而是在与改不改变
#include
using namespace std;
class demo{
// 非const成员函数可以访问,const成员变量
public:
demo(int n, char c , int *p):
a(n),ch(c),b{p[0], p[1], p[2]} //初始化列表格式,分别对int,char,数组,进行的初始化
{
}
void printf_demo()
{
cout<
3.const修饰类
1.const修饰的对象,只能访问有const修饰的函数
四.友元函数
面向对象的特点
【
1.封装:安全
2.继承
3.多态
】
友元函数
#include
using namespace std;
class demo{
private:
friend void func(demo A); //友元函数声明
int a;
};
void func(demo A)
{
cout<
作用:友元函数可以访问类的私有空间
一.全局函数作为友元函数
二.友元类 向前声明、
#include
using namespace std;
class B; //向前声明
class A{
private:
friend class B;
int i;
};
class B{
public:
void func(A obj)
{
cout<
三.类的成员函数是另一个类的友元函数
#include
using namespace std;
class A;
class B{
public:
void func(A obj);
private:
};
class A{
public:
friend void B::func(A obj);
private:
int i;
};
void B::func(A obj)
{
cout<
1.友元函数内部没有this指针
2.打破了封装,不安全(避免使用)
3.需要频繁访问数据,使用友元会更快捷
关键字 friend