《王大哥C++视频(”最牛逼“C++视频,没有之一)》学习笔记4

1.赋值运算符重载

  1.发生时机:用一个已有对象,给另一个已有对象赋值。两个对象均已创建结束后,发生的赋值行为。

   2.系统默认提供赋值运算符重载,一旦自实现,则不再提供。

   3.系统默认的是等位拷贝(即浅拷贝),会造成重析构,从而使内存泄漏。

   4.在此情况下的等位拷贝的问题:

     1.导致自身的内存泄漏( 等位拷贝是将其赋值量的地址赋给被赋值量,使被赋值量原来指向的地址没有了指向,从而导致内存泄漏。)

      2.导致重析构(1中解释表示两个量指向同一个地址,从而导致其地址呗析构两次。)

      3.自赋值(属于人为,即特意写出自赋值代码,如:a=a;)

   5.自实现赋值运算符重载(解决等位拷贝问题)

      1.被赋值量先将自己指向的地址释放掉

      2.制造出一个与赋值量内存大小一样的空间,使被赋值量指向新的空间

      3.最后将赋的值赋给被赋值量。

      4.解决1中的自赋值问题:在进入拷贝构造时便判断是否是自身,若是则退出不做任何操作。

      5.在 自实现拷贝构造器中返回语句为:return  *this;其为了实现连等功功能(a=b=c)

自实现赋值运算符重载代码:

MyString &MyString::operator =(const MyString &another)
{
    if(this->_str=another._str)
        return *this;
    delete []_str;
    int len=strlen(another._str);
    _str=new char[len+1];
    strcpy(_str,another._str);
    return *this;
}

2.+运算符重载(返回的是对象,不是引用)

  重载功能:将 字符串连接在一起

  实现:

    1.先定义一个临时的中间类对象,用于将两个字符串连接在一起。

    2.将对象中的数据成员内存释放。

    3.为其重新分配新的空间(长度为两个字符串的总长度),若下面用strcpy函数则应先清空(新分配的空间有可能存放着垃圾值,而strcpy是从\0后开始拷贝,若前面有一些垃圾值,则结果会有误。),用memset(要清的内存,0,内存的长度)函数清空

    4.用strcat函数将两个字符串连接在一起(先连接第一个,在连接第二个,顺序别搞反了)。

    5.返回中间临时对象

String String::operator +(const String &anoter)
{
    String temp;
    delete []temp._str;
    int len=strlen(this->_str);
    len +=strlen(anoter._str);
    temp._str=new char[len+1];
    memset(temp._str,0,len+1);
    strcat(temp._str,this->_str);
    strcat(temp._str,anoter._str);
    return temp;
}

加了memset函数的结果:

没加memset函数的结果:

3.比较运算符重载(下标运算符[]、>、<、==)

  

char& String::operator [](int idx)
{
    return this->_str[idx];
}

bool String::operator >(const String &another)
{
    if(this->_str>another._str)
        return true;
    else
        return false;
}

bool String::operator <(const String &another)
{
    if(this->_str<another._str)
        return true;
    else
        return false;
}

bool String::operator ==(const String &another)
{
    if(this->_str==another._str)
        return true;
    else
        return false;
}
4.const修饰符  可修饰数据成员、成员函数、类对象     1.在修饰数据成员时,      初始化位置只能在参数列表里。      被const修饰的数据成员,不能被修改     2.修饰成员函数时,      位置放在函数声明之后,实现体之前【void print()  const   {   }】,要求在声明和定义处都要有const关键字。         意义:表示不会通过任何方法修改类数据成员,即能访问const和非const数据成员,但不能修改非const数据成员,也不能通过其类成员函数修改,只能访问const成员函数。

        可构成重载         const  对象只能调用const成员函数。         非const成员对象,优先调用非const成员函数,若无,则可调用const成员函数。      3.修饰类对象         const   修饰函数,是从函数的层面,不能修改数据         const   修饰对象,是从对象的层面,不能修改数据,只能调用const成员函数 

5.static修饰符(静态:静态变量,静态函数)  

  在C中  可修饰全局变量、局部变量

    修饰全局变量:改变作用域,使其仅限用于本文件

    修饰局部变量:改变生命周期(局部变量是随用隋开,用完即消,用static修饰之后与主函数生命周期一样)、存储位置(未修饰的局部变量放在栈上、被static修饰之存放data段的bss段(未初始化)或 rw段(初始化))

  在C++中  

    在类内部,用来实现族类对象间的数据共享。

        在生成对象时,普通数据成员才有空间。而static数据成员在类声明时就已经开辟了空间。

        static数据成员既属于类(能用类访问),也属于对象(也能用对象访问),但终究属于类。【即:在没有对象生成时,可用类名访问static数据成员】

        static修饰数据成员:在类内定义,在类外定义:类型名  类名::变量名=初值;

    static修饰成员函数:只用于管理static数据成员。

        static修饰的成员函数既属于类(能用类访问),也属于对象(也能用对象访问),但终究属于类。【即:在没有对象生成时,可用类名访问static成员函数】

        static修饰的成员函数,因为它属于类,所以没有this指针。不能访问非static数据成员和成员函数。

      

6.指向类成员的指针

  指向类数据成员的指针:

      定义:类型名  类名::*指针

      初始化:类型名   类名::*指针=&类名::非静态数据成员

      指向非静态数据成员的指针在定义时必须和类相关,在使用时必须和具体的对象关联

      解引用:  类对象名.*指针  或  类对象名->*指针

  指向类成员函数的指针:

      定义:类型名  类名::*指针(参数列表)

      初始化:类型名   类名::*指针(参数列表)=&类名::非静态成员函数

      解引用:  类对象名.*指针  或  类对象名->*指针(参数列表)

时间: 2024-10-15 06:22:00

《王大哥C++视频(”最牛逼“C++视频,没有之一)》学习笔记4的相关文章

C PRIMER PLUS 学习笔记(一)

1显示程序执行的窗口一闪即逝.可以添加如下语句: getchar() 作用是获取键盘输入. 2 inf 和 nan float toobig = 3.4e38 * 100.0f; float not_a_number = asin(1.2);//math.h printf("%e \t %e\n", toobig,not_a_number); inf-表示无穷大,nan-Not-a-number 3 long double 的输出格式 long double x; x = 3.2e-5

C++ Primer Plus学习笔记之虚函数

C++ Primer Plus学习笔记之虚函数 C++语言的多态性有两种类型:静态多态性和动态多态性.函数重载和运算符重载就是静态多态性的具体表现,而动态多态性是指程序运行过程中才动态的确定操作所针对的对象,它是通过虚函数实现的: 1,虚函数的概念: 一个指向基类的指针可用来指向从基类派生的任何对象,这样就可以达到一个接口多个实现的访问了:虚函数是在基类中被冠以virtual的成员函数,它提供了一种接口界面.虚函数可以在一个或者多个派生类中被重新定义,但要求在派生类中从新定义时,虚函数的函数原型

C++ Primer Plus学习笔记之静态成员

C++ Primer Plus学习笔记之静态成员 关键字static可以用来说明一个类的成员(包括数据成员和成员函数),这样的成员被称为静态成员: 1,静态数据成员 在一个类中,若将一个数据说明前加上static,则该数据成为静态数据,静态数据成员被该类的所有对象共享.无论建立多少个该类的对象,都只有一个静态数据存储空间: 具体语法如下: 类型名 类名::静态数据成员[=常量表达式] 其中,常量表达式用于初始化类的静态数据成员: 静态数据成员属于类,而不属于对象,因为静态成员的存在是不依赖于某个

C++ Primer Plus学习笔记之继承类的初始化顺序

C++ Primer Plus学习笔记之继承类的初始化顺序 基类的构造函数,析构函数和操作符函数operator=是不能被派生类继承的: 那么,当创建一个派生类对象时,怎样调用基类的构造函数对基类的数据进行初始化呢??? 答案是:构造函数执行时遵行先兄长(基类),再客人(对象成员),后自己(派生类)的顺序: 另一方面,执行析构函数时,先执行派生类的析构函数,再执行基类的析构函数.原因是,对基类的破坏隐含了对派生类的破坏,所以派生类的析构函数必须先执行: #include<iostream> u

C++ Primer Plus学习笔记之运算符重载

C++ Primer Plus学习笔记之运算符重载 1,成员函数和友元函数选择的建议 下面我们先看两个例子: 成员函数重载 #include<iostream> using namespace std; class Complex { public: Complex(double r=0,double i=0) { re=r; im=i; } Complex operator+(const Complex& obj); Complex operator!(); void Display

C++ Primer Plus学习笔记之拷贝构造函数

C++ Primer Plus学习笔记之拷贝构造函数 1,什么是拷贝构造函数 拷贝构造函数有两个含义: 首先,它是一个构造函数,当创建一个新对象时,系统自动调用它: 其次,它将一个已经定义过的对象的数据成员逐一对应的复制给新对象: 如果一个类没有显式定义拷贝构造函数,C++编译器可以为该类产生一个缺省的拷贝构造函数.这个缺省的拷贝构造函数采用C的方式,将拷贝对象的内存一个字节一个字节的拷贝到拷贝对象的内存中(内存拷贝): 2,拷贝构造函数的作用 (1)创建一个新对象,并将一个已存在的对象拷贝到这

c++ primer plus学习笔记(栈指针)

c++ primer plus 程序清单14.5 程序清单14.6 模拟如下情况: 某人将一车文件交给plodson,如果plodson的收取蓝是空的,他将取出车中最上面的文件,将它放入收 取蓝,如果收取蓝是满的,他将取出栏中最上面的文件,并进行处理,然后放入发出蓝,如果收取蓝不空不满 plodson将采用抛硬币的方式来决定采取措施. 很明显,我们需要使用栈去管理上述文件. 1 #ifndef STACK_H_ 2 #define STACK_H_ 3 4 //定义类模板 5 template

《c++primer》学习笔记

花了一个多月时间总算是把这本书看完了,再去看自己家游戏的服务器的代码还是很难懂,里面用到了好多boost库的东西,不过这些东西很多都已经加入了c++11的新标准里了,要到自己能做服务器还得接着学,所以接下来的一个月开始看<C++标准库>. 把看<c++primer>的时候抄的笔记先誊在这里方便以后参考. #include 来自标准库的头文件使用<> 来自非标准库的头文件使用"" ------------------------------------

c++ primer plus 学习笔记

我的机子用Xcode,单位是字节 0开头为8进制 0x为16进制 cout默认输出的是10进制 wchar_t 宽字节,它是一种足够大的整形类型,可以用来表示的是比如中文的编码 c常量一旦被定义,就不能被修改(const) 浮点数,c++中浮点数在计算内存中由两部分组成,一部分为基数,一部分用来表示浮点,这个浮点是用二进制来表示. 非常大或者非常小的数可以用e表示法来表示 这个程序充分说明了精度的问题,double能保存更高的精度.对于c++来说float只能保存6位有效数字,如果需要更高的精度

《C++ Primer》学习笔记【第一部分 基本语言】

第2章 整型的赋值:当我们试着把一个超出其范围的值赋给一个指定类型的对象时,结果如何?答案取决于类型是signed还是unsigned的.对于unsigned,编译器会将该值对unsigned类型的可能取值数目求模然后取所得值:对于signed类型,未定义行为,很多处理器处理方式和unsigned类似. 字符串字面值的连接:std::cout << "multi-line" L"literal " << std::endl;结果未定义,即连接