关于类和对象的浅析

来源:互联网 发布:华为手机删除数据恢复 编辑:程序博客网 时间: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修饰的成员变量算作类的成员,但在计算类的大小时,不算在其中。

       


       如在阅读中发现错误,或者不准确的地方,请在评论区留言。希望大家支持!



1 0
原创粉丝点击