关于类和对象的浅析
来源:互联网 发布:华为手机删除数据恢复 编辑:程序博客网 时间:2024/05/20 23:35
类的定义:
类,最初步的说,其实就是对C语言中结构体的拓展。因为c++有了类,才使c++面向的是对象,也可以说是C语言和C++在明显的区别;在类中,我们可以自定义变量,自定义函数。并且,在类中,在类中,定义的变量默认的权限都是私有private的,即在类中,若你不声明一下变量或者函数为公共public的,编译器就会认为你这个是私有private的,私有的类型在类外无法对其进行访问,所以,想像C语言中对它进行赋值、修改之类的都会出错。在类中,有六大基本隐含函数,还有友元等函数的拓展。
class student //这个中省略了类中的其他函数,只是为了方便解释私有和公共
{ //这就是一种默认情况的,没有声明,所有类中变量都是私有
char a;
int c;
double c;
};
class Student //Student这个类中定义的变量在public的关键字下,所有一切都是公共的,即在类外可以正常访问
{
public:
char d;
int e;
double f;
};
一半情况下,我们把类中的所有成员变量都设置成private型的,而把类中的成员函数都设置成public型,假入我们要在函数外更改类的成员变量时,我们在public下定义一个获取成员变量的函数,这样,我们既可以在类外更改相应的值,又保证了类的封装特性。
类的六大成员函数分别是:构造函数,拷贝构造函数,析构函数,运算符重载,取地址符重载,const修饰的取地址符重载。
构造函数:
构造函数的函数名与类名相同;
没有返回值;
有初始化列表(可以不用);
新对象被创建时,编译器自动调用,且在对象的生命周期内仅被调用一次;
构造函数可以重载,实参决定到底调用哪个构造函数;
如果没有显式定义,编译器会自动生成一个默认的最简单构造函数并调用;
无惨构造函数和带有缺省的构造函数都是构造函数,但缺省构造函数只有一个。
拷贝构造函数
只有单参;
该形参是对本类类型对象的引用;
创建对象时使用已存在的同类对象来进行初始化;
编译器自动调用;
没有返回值;
析构函数:
析构函数是释放空间的;
析构函数没有参数;
没有返回值;
运算符重载:
在类中,如果要使用对于正常变量的“+”、“-”、“*”、“/”...时,无法直接使用,这时,我们就需要对运算符进行重载,以便可以对类的对象进行预期的加减乘除等一系列操作。
运算符重载的关键字为“operator”,在operator前加上返回值类型,operator后直接加上需要重载的符号,例如:
student operator+(const student& s){ student S; S.a = a + s.a; return S;}这可以继续穿插一个“this指针”的问题,this指针是编译器自动产生的,存在当前的类中,this指针的指向就是当前对象,在构造函数、析构函数、拷贝构造函数中虽然无参,或者之后一个参数,但是总有一个隐含的参数,即this指针,之前说的几个函数的参数里面都可以加上一个: student* this,student是我定义的类名。你也可以定义成teacher、worker...
地址符重载
取地址运算符其实在不重载时也可以取当前对象的地址,如下面的一段代码:
#define _CRT_SECURE_NO_WARNINGS#include <iostream>using namespace std;class student{public:student(int a = 1, int b = 2, int c = 3): _a(a), _b(b), _c(c){ }student(const student& s){_a = s._a;_b = s._b;_c = s._c;}private:int _a;int _b;int _c;};int main(){student s1;cout << &s1 << endl;system("pause");return 0;}它输出的是:
但是,我们现在再写一个重载的取地址函数
student* operator&(){return this;}
再看看结果:
虽然二者都可以正常输出地址, 但我们很明显的发现,二者的地址并不想通过,说明没有重载的取地址符还是在一定程度上并不适用于对象。
赋值运算符的重载:
student& operator=(const student& s) // 默认的有this指针{_a = s._a;_b = s._b;_c = s._c;return *this; // 因为this是一个指针,而返回值是一个类的对象的引用} // 所以返回this的解引用main函数中的简单逻辑
int main(){student s1;student s2(10, 20, 30);s1 = s2;cout << s1 << endl;cout << s2 << endl;system("pause");return 0;}但是我们在使用cout打印对象时,还要对"<<"进行重载,使之符合类的输出规则
friend ostream& operator<< (ostream &os, student&s); //此部分要在类内声明
ostream& operator<< (ostream &os, student&s) //函数的定义部分要放在类外和main函数外{os << s._a << " " << s._b << " " << s._c;return os;}friend是一个关键字,表明在friend后面声明的函数是一个友元函数,可以调用该函数的私有成员变量,使问题变得很简单,但是破坏了类的封装特性。
总之,现在我们就得到了赋值运算符重载过后上面main函数中的逻辑的结果
const修饰的取地址符重载
const Date * operator& () const{ return this;}这个const修饰过的取地址符重载的好处就在于将当前对象的this指针的权限更改为const student* const this,无法更改this的指向和他所指的值。
const的作用
const的作用很大,类中的函数基本都有一个默认的参数--this指针,而const修饰的就是this指针,没有const修饰的this指针的形式形如 student *const this,const修饰的this指针形如const student* const this,即修饰过后的this指针不仅无法更改指向,也不能更改this指向的值。
不能给静态成员函数使用const修饰;
非成员函数不允许用从const修饰;
一半在表示函数参数时,将&和const一起使用;
一般const的使用为:
student& GetNum(const student& s)const // 即在函数名称的后面直接加上const,这样就可以修饰this指针了在这个函数中,this指向的值不可被更改,并且这个函数中也不能调用不含this指针修饰的函数,因为嵌套的函数没有const修饰,即表明this指向的值可被修改,与嘴外层矛盾。但不含const修饰的函数包含的有const修饰的函数时可以正确运行。
错误示例:
student& GetNum(const student& s1)const{student& SetNum(const student& s2){...;}}正确示例:
student& SetNum(const student& s2){student& GetNum(const student& s1)const{...;}}static的用法和作用:
static的作用在C语言中就是修饰成静态变量或者静态函数,静态变量就是在第一次调用这个变量时进行初始化,以后都使用这个值的上一次的旧值,一半在循环中会搅乱我们的思维。就像这样:
void fun(){int i = 0;static int a = 0;int b = 0;printf("a=%d,b=%d\n", a, b);a += 1;b += 1;}int main(){int i = 0;for (; i < 10; i++){fun();}system("pause");return 0;}正确的输出结果位:
而static在修饰函数时,表明此函数只能在本文件中调用,有效保证了函数实现的保密性。
static在C++的类中也表示该变量是一个静态变量,这个静态变量可以直接用类名加限定符访问,表示类中的成员的值,而不是表示当前对象中该变量的值。且该变量在类外要重新定义,如
static int count; //类内的定义 int student::count ; //类外的定义对于static修饰的成员函数,则表示在当前函数内不存在this指针,所以一般情况下此类函数不会对当前对象产生影响。且就是因为static修饰的时候不支持this,所以才造成static修饰的成员变量不受某一确定对象的限制。
static修饰的成员变量算作类的成员,但在计算类的大小时,不算在其中。
如在阅读中发现错误,或者不准确的地方,请在评论区留言。希望大家支持!
- 关于类和对象的浅析
- 对于关于类和对象的感悟
- 关于对类和对象的理解
- 关于类和对象的进一步讨论
- c++关于类和对象的实例
- 关于类和对象
- 关于类和对象
- java 对象的浅析
- 浅析Oracle对象和数据的导入导出
- 继承对象的构造和析构浅析
- 浅析多线程的对象锁和Class锁
- 类与对象浅析
- 关于distinct 和group by的去重逻辑浅析
- 关于distinct 和group by的去重逻辑浅析
- 关于distinct 和group by的去重逻辑浅析
- 关于distinct 和group by的去重逻辑浅析
- 关于distinct 和group by的去重逻辑浅析
- 关于CSS-RESET的浅析和个人理解
- Java自带线程池和队列详细讲解
- Java io
- 统计某个字符串出现的次数或者是否存在
- C++编程 学习笔记(一) 初识
- 安卓系统定制:android的充电图标的制作和显示
- 关于类和对象的浅析
- 分治算法
- MySql之运算符学习总结
- Android自定义View(六)_Canvas之画布操作
- ssm整合
- FEB
- 【BZOJ 3714】[PA2014]Kuglarz 最小生成树
- unbuntu 下进度条小程序
- java中list set map 学习