【笔记-C++】 class
来源:互联网 发布:用友软件 t系列 编辑:程序博客网 时间:2024/06/05 00:25
与结构体区别
struct包装数据,函数包装代码,类既包装数据,也包装代码
class和struct都可以描述对象
struct可以使用{..............}初始化对象,class只有在最新的标准才可以使用这种初始化的方法(需要public)
struct A
{
void fun(){cout<<"xxx"<<endl;}
int a;
double b;
};
可以使用A a={1,1.2};
如果把struct换成class则可能无法使用该种赋值方式
权限
struct默认是完全公开的,class默认是私有的
private:只有在类内可以使用
public:在类内外都可以使用
在class中加public:则此语句下的内容都可以在类外和类内访问,直到遇到下一个权限的修饰语
class A{..................};
A a; 构造函数无参时,此行不可写成A a()
A *p=new A();
new 后放的是A的构造函数
类的基本函数
class A{......
public: (如果定义构造函数,则不能省略)
A(){......}
构造函数重载 A(int x, int y):a(3),b(x),y(y)初始化参数{.....}
A(int x=1){....}
拷贝构造 A(const A&a){.....}
稀构函数 ~A(){........}
声明和实现分开时:初始化参数列表放在实现部分,参数的默认值在声明部分指定,函数前的static修饰放在声明处,函数的const修饰在声明和实现部分都写。
构造、析构都有系统默认的,如过要自定义,会覆盖系统的。此类函数无返回值
拷贝构造内的A&a可以不写a,如果拷贝构造的操作中有需要使用a,才必须写上
构造函数
构造函数在对象创建时调用一次
A a; 创建一个栈对象,同时调用无参构造
A a(10); 创建一个栈对象,调用有参构造(传入参数10)
A *p=new A(); 创建一个堆对象,同时调用无参构造(无参构造时也可用 A *p=new A)
A(x=1)和A()在使用A()调用时会产生冲突
const变量只能在初始化时赋值(初始化参数列表中进行),初始化参数列表中写成A(),如果A是基本类型,则A的值变为0,如果A是类类型,则为无参构造(继承中用)
拷贝函数
拷贝构造函数调用时间:在使用同类型的对象构建一个对象(复制);在函数参数值传递;函数返回对象一旦有拷贝操作就调用
使用时:A a; A b=a;
不可写成A a;A b; b=a;
1)A get(){A a;return a;}
A c=get();
不用拷贝构造,系统自动优化
2)A get(){A *a=new A(); return *a;}
A c=get();
会调用拷贝构造,因为使用了堆
自定义拷贝构造时,必须同时定义构造函数,不可以只定义拷贝构造(可以只定义构造,不定义拷贝)
析构函数
析构函数中执行释放内存可能会造成内存泄漏。
在栈中将class创建出对象后,会在程序某行之后不再出现该对象时,自动调用析构函数(在最后一次出现对象的行调用)
析构函数用来释放内存
可单独调用~A() 堆内层时必须单独调用析构,因为堆内存不会自动调用析构函数
exp:A *a=new A();
a->~A()
虚析构函数
(在析构前加virtual),基类有虚函数,基类对象的指针指向子类对象(多态条件时),释放基类对象的该指针时,如果基类析构函数不是虚函数,则子类析构函数的调用行为未定(不调用),把基类中析构变为虚函数,则会调用子类构造,同时也会调用基类的析构。
构造函数不能为虚函数(拷贝构造,构造)
深拷贝
当要拷贝的对象中有指针变量时,会使用拷贝前后两个对象中的指针指向同一块堆内存,在其中一个对象释放堆内存后,另一对象中指针指向的是一块已经释放的内存,再次释放会出错,解决此问题需要使用深拷贝方式(自己定义拷贝过程)
class A{
int m;
int *n;
A():m(10),n(new int(8)){}
A(const A&a):n(new int){
m=a.m; *n=*(a.n);
}
~A(){
if(n!=NULL){delete n; n=NULL;}
}
};
1)构造函数为指针分配堆内存
2)拷贝构造函数为拷贝出的对象的指针分配新的堆内存,并进行其他数据的拷贝
3)自定义析构函数释放堆内存(也可以不使用if语句进行判断,因为有时候没有给类的指针成员分配内存,而是指向null,可以不用释放,delete NULL也不会出问题)
因为有了1)和3)所以才需要2)的步骤。
拷贝构造和赋值函数
编译器会自动生成缺省的拷贝构造和赋值函数,如果不想编写这两个函数,也不希望默认的被调用,则可以将这两个函数声明为私有的。
this指针
this是指向当前对象的指针,*this代表当前对象。构造对象时,指向正在构建的对象,成员函数中,指向这个函数的对象
当函数形参与成员变量重名时,可以用this区分:
class A{
int b;
public:
A(int b){this->b=b;}
};
可使用this返回数据,可作为参数传递
静态成员、函数
静态成员:类和类的对象所共享的函数、数据(相当于全局变量、函数,存在于全局区,不属于对象,只是访问范围限制在类内),不需要对象,只需要类型就可以访问。
声明和实现分开时,函数前的static修饰放在声明处。
静态成员必须在类外(全局区)进行初始化操作,不能在类的初始化中进行赋值。
class A{ public: static int x;};
int A::x=0;
类内函数或类的对象,能直接访问类内的静态变量、函数。
类外调用静态成员、函数[需要是public]
A::x;
A::fun();
静态函数只能直接访问静态成员,不能直接访问非静态成员,因为无this指针。如果想在静态函数中访问非静态成员,可以传入一个指针:
static void ab(A *a){ cout<<a->m<<endl;}
成员指针
typedef void (A::* FUN)(int a);
类型是:void (A::*)(int);
//赋值
FUN f = &A::f1;
使用:
(a.*f)()
(this->*f)()
成员指针直接输出时为1
用联合可以输出指针指向的地址
union{int A::*p; void *pr;};
用pr可以输出指向的地址
const对象和函数
const对象只能调用const函数,声明和实现分开时,函数的const修饰在声明和实现都需要写。
1)const A a; const对象
2)void ab() const{..........} const函数(类内)
void ab(){.................}
以上两个函数构成重载(非const函数优先调用非const函数,如果无非const函数,就用const)
const函数不能修改普通成员变量,如需修改,则在成员前加mutable修饰
exp: mutable int m;
void ab()const{m=10;}
友元
友元函数:在全局函数中要调用类中私有成员,需要在类中用friend声明一下这个全局函数。则该全局函数可访问到类中私有成员(通过类的对象)
exp:
class A{int x;};
A a;
void ab(A a){cout<<a.x<<endl;}
把class改为:
class A{
int x;
friend void ab();
};
友元类:
friend class B;
在B继承A时,使用友元类,可以使B能访问到A的private成员
- 【笔记-C++】 class
- C#/WPF学习笔记:class 与 struct
- Object-C学习笔记(二)---类class
- C.Class
- [C++]Class
- Object-C 学习笔记(十九)---#include 、#import 、@class
- OBJ-C内存管理+@property参数+@class+autorelease学习笔记
- The MD4 Class.(C#)
- c ++ class和struct
- The MD4 Class.(C#)
- The MD4 Class.(C#)
- C++-Class Summary
- Qt4 Dialog Class (C++)
- Objective-C Class Selector
- drivers\base\class.c
- Objective-c @Class 说明
- [C++] friend class
- Objective-c中 @class
- html+css基础视频80-88/表格和表单的使用
- vs2015下opencv3.3扩展opencv_contrib模块并使用SiftFeatureDetector等函数
- 学python(04)——函数生成N位验证码
- java实现验证身份证号是否合法
- day10_进程、协程、异步IO、多路复用
- 【笔记-C++】 class
- NIO
- GBDT算法
- 使用vue做前端开发时涉及到npm的一些常用指令
- Python3.x和Python2.x的区别
- C语言-程序
- mysql中in与exists效率比较
- 网站标题的长短对SEO优化的影响
- Ubuntu 16.04 安装NVIDIA驱动,解决循环登录的问题