zoukankan      html  css  js  c++  java
  • C++默认成员函数

    1.什么是面向对象?#

    概念:(Object Oriented Programming,缩写:OOP)是一种程序设计范型,同时也是一种程序开发的方法。
    对象指的是类的实例,将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性。

    面向对象设计

    C++不是纯面向对象语言,而是基于面向对象的语言
    (ps:因为它包含C的部分,C是面向过程)

    面向对象三大特性:封装、继承、多态

    2.类的大小?为什么要内存对齐?内存对齐的计算?空类的计算

    ①类的大小(是不是很疑惑,类肿么还有大小,不就是个类型嘛,纳尼)
    是的类有大小,看个栗子:

    class Book
    {
    public:
    	Book();
    	void Show( );
    private:
    	char name[10];
    	int isbn;
    };
    

    sizeof(Book);会是多少?
    这里写图片描述
               有没有算出来。
    其实类和我们结构体一样是有大小的,而且类的内存对齐方式和结构体一样。
    ②为什么要内存对齐?
    这个要说到操作系统上了,我们的cpu把内存当成是一块一块的,块的大小可以是2,4,8,16 个字节,因此CPU在读取内存的时候是一块一块进行读取的,块的大小称为(memory granularity)内存读取粒度。
    为什么要分块呢?(分块读取有利于提高内存访问效率)
    和内存对齐有什么关系?
    假设CPU要读取一个4字节大小的数据到寄存器中(假设内存读取粒度是4),分两种情况讨论:
    1.数据从0字节开始
    2.数据从1字节开始
    解析:当数据从0字节开始的时候,直接将0-3四个字节完全读取到寄存器,结算完成了。当数据从1字节开始的时候,问题很复杂,首先先将前4个字节读到寄存器,并再次读取4-7字节的数据进寄存器,接着把0字节,4,6,7字节的数据剔除,最后合并1,2,3,4字节的数据进寄存器,对一个内存未对齐的寄存器进行了这么多额外操作,大大降低了CPU的性能。
    所以内存对齐就很好的提高了cpu的读取效率。
    内存对齐的计算?
    1.第一个成员在与结构体变量偏移量为0的地址处。
    2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
    VS中默认的值为8
    gcc中的默认值为4
    3.结构体总大小为最大对齐数(每个成员变量除了第一个成员都有一个对齐数)的整数倍。
    4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
    空类的计算
    先说答案:空类的大小是1
    这里写图片描述

    3.类的6个默认成员函数的详细使用及细节

    c++的类有六个默认成员函数:
    默认成员函数
    我们常用的是前四个。
    1)构造函数:
    成员变量为私有的,要对它们进行初始化,必须用一个公有成员函数来进行。同时这个函数应该有且仅在定义对象时自动执行一次,这时调用的函数称为构造函数(constructor) 。
    构造函数是特殊的成员函数,其特征如图:
    这里写图片描述
    构造函数基本我们都使用全缺省的重载函数。

    2)拷贝构造函数:
    创建对象时使用同类对象来进行初始化,这时所用的构造函数称为拷贝构造函数(Copy Constructor),拷贝构造函数是特殊的构造函数。
    来个例子:

    class Book
    {
    public:
    	Book( );
    	Book(int isbn = 0x00, char *name = "图书");
    private:
    	int isbn;
    	char *name;
    };
    
    int main( )
    {
    	Book b( );
    	Book b1(b); //这里使用了拷贝构造
    	system("pause");
    	return 0;
    }
    

    特征:
    拷贝构造函数其实是一个构造函数的重载。
    拷贝构造函数的参数必须使用引用传参,使用传值方式会引发无穷递归调用。(思考为什么?)
    若未显示定义,系统会默认缺省的拷贝构造函数。缺省的拷贝构造函数会,依次拷贝类成员进行初始化。
    一般情况下我们会使用系统默认的拷贝构造函数,但是在特殊情况下需要显示定义(比如链表的拷贝构造)
    3)析构函数
    当一个对象的生命周期结束时,C++编译系统会自动调用一个成员函数,这个特殊的成员函数即析构函数(destructor)
    构造函数是特殊的成员函数,其特征如下:
    析构函数在类名加上字符~。
    析构函数无参数无返回值。
    一个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省的析构函数。
    对象生命周期结束时,C++编译系统系统自动调用析构函数。
    注意析构函数体内并不是删除对象,而是做一些清理工作。(怎么理解这里的清理工作?参看下面的代码)

    class Date
    {
    public :
    // 析构函数
    ~Date()
    {}
    private :
    int _year ;
    int _month ;
    int _day ;
    };
    
    class Array
    {
    public :
    Array (int size)
    {
    _ptr = (int *)malloc( size*sizeof (int));
    }
    // 这里的析构函数需要完成清(shi)理(fang)工(kong)作(jian)。
    ~ Array ()
    {
    if (_ptr )
    {
    free(_ptr );
    _ptr = 0;
    }
    }
    private :
    int* _ptr ;
    };
    

    4)赋值操作符重载
    为了增强程序的可读性,C++支持运算符重载。
    运算符重载特征:
    operator+ 合法的运算符 构成函数名(重载<运算符的函数名:operator< )。
    重载运算符以后,不能改变运算符的优先级/结合性/操作数个数。
    5个C++不能重载的运算符: .*/::/sizeof/?:/.

    5)取地址操作符重载

    class Date
    {
    public :
    Date* operator &()
    {
    return this ;
    }
    const Date * operator&() const
    {
    return this ;
    }
    private :
    int _year ; // 年
    int _month ; // 月
    int _day ; // 日
    };
    

    6)const修饰的取地址操作符函数
    在成员函数后面加const,const修饰this指针所指向的对象,也就是保证调用这个const成员函数的对象在函数内不会被改变。

    class Date
    {
    public :
    void Display ()
    {
    cout<<"Display ()" <<endl;
    cout<<"year:" <<_year<< endl;
    cout<<"month:" <<_month<< endl;
    cout<<"day:" <<_day<< endl<<endl ;
    }
    void Display () const   //const成员函数
    {
    cout<<"Display () const" <<endl;
    cout<<"year:" <<_year<< endl;
    cout<<"month:" <<_month<< endl;
    cout<<"day:" <<_day<< endl<<endl;
    }
    private :
    int _year ; // 年
    int _month ; // 月
    int _day ; // 日
    };
    void Test ()
    {
    Date d1 ;
    d1.Display ();
    const Date d2;
    d2.Display ();
    }
    

    后两个成员函数用的很少。

    详细例题会在后面博文中专门解释。

    原文链接:https://blog.csdn.net/qq_38646470/article/details/79736221
    专栏链接:https://blog.csdn.net/column/details/20026.html

  • 相关阅读:
    windows7管理员权限
    Linux编程 第一个Hello World的C程序
    初步接触XCode和IPhone Simulator
    Android调用WCF
    mysql常用命令
    怎样利用Python制作守护进程
    Android模拟器如何设置DNS访问局域网内网站
    ubuntu下mysql攻略
    IIS7快速启动
    内存出错有时候是free后没有给指针赋NULL
  • 原文地址:https://www.cnblogs.com/zhonglongbo/p/8796464.html
Copyright © 2011-2022 走看看