C++入门学习11 面向对象2

this指针初探

this关键字
this指针

  • 每个成员函数(包括构造和析构)都有一个this指针
  • this指针指向调用对象,即可以通过this关键字访问当前对象的成员
    访问成员变量
    this -> 成员名;
    访问成员函数
    this -> 函数名();

    在这里插入图片描述
    this 在 C++ 是函数的隐含第一个参数。只能在函数内部使用
    在这里插入图片描述
    在这里插入图片描述
    在函数的结尾声明为const: 函数内部不允许修改对象本身,调用本对象非const方法就会报错

大程序使用 new. 栈内存消毁问题。

初始运算符重载

  • 运算符重载 重点- 难点
  • 友元函数
  • 一元运算符重载
  • 重载 << 运算符 重点
  • 类的自动转换和强制类型转换

运算符重载(Operator Overloading)

运算符重载就是“想法转换”,他的目标是简化函数调用的方式

  • 把标准的函数使用方式,重新定义为自己认为的方式
    所谓重载,就是赋予新的意义
    运算符重载也是一个道理,同一个运算符可以有不同的功能

实际上,我们已经不知不觉中使用了运算符重载

  • +号可以对不同类型(int,float等)的数据进行加法操作
  • <<既是位移运算符,又可以配合cout向控制台输出数据
  • C++本身已经对这些运算符进行了重载在这里插入图片描述
  • 在这里插入图片描述
    那个是编译器的内部调用,程序员是不能使用那个语句的。
#include <iostream>
#include "Integer.h"
using namespace std;


void TestInteger();

int main()
{
    //cout << "Hello world!" << endl;
    TestInteger();
    return 0;
}
void TestInteger()
{
    Integer int1(1024), int2(2048), int3;
    int3 = int1 + int2;
    cout <<"int3 = int1 + int2的结果为:" << int3.IntValue() << endl;
}


```cpp  .h
#ifndef INTEGER_H
#define INTEGER_H

//我们自己定义的整型类,将整型封装成类,以便实现面向对象的封装
class Integer
{
    public:
        Integer();
        Integer(int value) : m_value(value){} //实现

        //重载+运算符
        Integer operator+(Integer other);

        int IntValue(){return m_value;}


        virtual ~Integer();

    protected:

    private:
        int  m_value;  //实际的整型数字 m---是member的意思,私有成员
};

#endif // INTEGER_H

#include "Integer.h"


//调用默认构造时,会为私有m_value 赋一个默认值为0
Integer::Integer() : m_value(0)
{
    //ctor
}
//重载+运算符

Integer Integer:: operator+(Integer other)
{
    Integer result(this -> m_value + other.m_value);    //用来返回的结果对象
    return result;


}
Integer::~Integer()
{
    //dtor
}

详解const

1.const修饰变量
在这里插入图片描述
num2 不能再去赋值–const

2.const能不能修饰指针变量?
在这里插入图片描述
1.只有一个const时,如果const位于的左侧 : 表示指针所指的数据是常量,不能通过该指针修改实际数据,指针本身是变量,可以指向其他内存单元
2.只有一个const时,如果const位于
的右侧:表示指针本身是常量,不能指向其他内存单元:所指向的数据可以修改
3.如果有两个const位于*的左右两侧,表示指针和指针所指向的数据都不能修改

3.const 修饰函数参数
在这里插入图片描述
都变成const就可以了调用了
void buy() const{}

4.const修饰返回值
在这里插入图片描述
在这里插入图片描述
const 在返回一个对象引用时更有效率。
强调:使用const修饰引用类型的一个常见的原因是:提高效率
如果函数要返回局部对象,就应该直接返回这个对象,而不要返回对象的引用。
局部对象会在使用后进行销毁
在可以返回对象,也可以可返回引用时,就应该首选引用,因为效率高
5.const修饰函数-说明函数不会修改成员变量的值
在这里插入图片描述
在这里插入图片描述
重载赋值符号
在这里插入图片描述

直接返回*this ,而不返回引用对象,更节省时间
在这里插入图片描述
二元运算符:+ - * / 取模

友元函数

在这里插入图片描述
因为友元函数没有this指针,则参数要有三种情况:

要访问非static成员时,需要对象做参数;

要访问static成员或全局变量时,则不需要对象做参数;

如果做参数的对象是全局对象,则不需要对象做参数.

可以直接调用友元函数,不需要通过对象或指针

复制构造函数

需求说明:

  • 自定义String(字符串)类,以简化字符串的操作

在这里插入图片描述
如果字符串长度为0的话,那么实例化为1的空间。空间取值为“/0”
在这里插入图片描述
头文件名字为String.h容易和string.h混不清楚。
改为myString

 private:
        int m_length; //字符串的实际长度,不包括/0
        char *m_value;  //实际存储字符的字符数组 在C++中一旦定义数组,就要给他长度。char m_value[]; 要给长度。
String::String() : m_length(0)
{
    //char * str = ''; //长度为0,但是实际的字符数组中会存在唯一的元素:\0
    this -> m_value = new char[1]; //不能是0----- 定义长度为0的时候,分配一个空间为1
    this -> m_value ='\0';
    friend ostream & operator <<(ostream & out,const String &str)
    {
    out << str.m_value;

    return 0

    }

*文件名;
*描 述;
*作 者;
*时 间;
*版 权;
*/
#include “MyString.h”

String::String() : m_length(0)
{
//char * str = ‘’; //长度为0,但是实际的字符数组中会存在唯一的元素:\0
this -> m_value = new char[1]; //不能是0----- 定义长度为0的时候,分配一个空间为1
this -> m_value =’\0’;
friend ostream & operator <<(ostream & out,const String &str)
{
out << str.m_value;

return 0

}


//ctor

}

String::~String()
{
//析构时,释放字符数组所指向的空间—如果不销毁的话,会造成内存泄露
delete[] m_value;

//字符串被销毁的时候,长度为0。但是指针所指的空间还存在。
//所以要销毁空间

//dtor

}
利用构造函数实现字符串的复制: 好处是在赋值的时候很方便

#ifndef STRING_H
#define STRING_H
#include<iostream>
#include <string >

using namespace std;

//自定义的字符串包装类

class String
{
    public:
        String();
        String(char * str);
        virtual ~String();
        friend ostream & operator <<(ostream & out,const String &str);

    protected:

    private:
        int m_length; //字符串的实际长度,不包括/0
        char *m_value;  //实际存储字符的字符数组 在C++中一旦定义数组,就要给他长度。char m_value[]; 要给长度。
};

#endif // STRING_H

#include <iostream>

#include <string.h>
#include "MyString.h"

using namespace std;

String::String() : m_length(0)

    //char * str = ''; //长度为0,但是实际的字符数组中会存在唯一的元素:\0
{
    this -> m_value = new char[1]; //不能是0----- 定义长度为0的时候,分配一个空间为1
    this -> m_value[0] ='\0';


}

  String::String(char *str)
  {
      //将传入的字符串str的值赋值给当前对象中的m_value

      if(NULL == str){
      this -> m_value = new char[1]; //不能是0----- 定义长度为0的时候,分配一个空间为1
      this -> m_value[0] ='\0';
      return;
      }
      m_length = strlen(str); //获得要复制字符串的长度
      m_value = new char[m_length +1];// 为/0留出一个空间

      strcpy(m_value, str);





  }
     ostream & operator <<(ostream & out,const String &str)
    {
        out << str.m_value << "\n";
        out << "str的长度:" << str.m_length;

       return out;
    }




String::~String()
{
   //析构时,释放字符数组所指向的空间---如果不销毁的话,会造成内存泄露
   delete[] m_value;

    //字符串被销毁的时候,长度为0。但是指针所指的空间还存在。
    //所以要销毁空间

    //dtor
}

#include <iostream>

#include <string.h>
#include "MyString.h"

using namespace std;

String::String() : m_length(0)

    //char * str = ''; //长度为0,但是实际的字符数组中会存在唯一的元素:\0
{
    this -> m_value = new char[1]; //不能是0----- 定义长度为0的时候,分配一个空间为1
    this -> m_value[0] ='\0';


}

  String::String(char *str)
  {
      //将传入的字符串str的值赋值给当前对象中的m_value

      if(NULL == str){
      this -> m_value = new char[1]; //不能是0----- 定义长度为0的时候,分配一个空间为1
      this -> m_value[0] ='\0';
      return;
      }
      m_length = strlen(str); //获得要复制字符串的长度
      m_value = new char[m_length +1];// 为/0留出一个空间

      strcpy(m_value, str);





  }
     ostream & operator <<(ostream & out,const String &str)
    {
        out << str.m_value << "\n";
        out << "str的长度:" << str.m_length;

       return out;
    }




String::~String()
{
   //析构时,释放字符数组所指向的空间---如果不销毁的话,会造成内存泄露
   delete[] m_value;

    //字符串被销毁的时候,长度为0。但是指针所指的空间还存在。
    //所以要销毁空间

    //dtor
}

利用构造可以直接通过你输入的参数判断,使用的是那个构造函数。可以直接出来结果

小结

  • 运算符重载就是“想法转换”,他的目标是简化函数调用的方式
    把标准的函数使用方法,重新定义为自己认为的方式
  • 友元函数
    流运算符<< 、>>,类型转换运算符不能定义为类的成员函数,只能是友元函数
    二元运算符在运算符重载时,一般声明为友元函数
  • 赋值/拷贝构造函数
    对于简单的类,默认拷贝构造函数一般是够用的,没必要再显式定义一个功能类似的拷贝构造函数
    当类拥有其他资源时,如动态分配的内存,打开的文件,指向其他数据的指针,网络连接等,默认拷贝构造函数就不能拷贝这些资源,必须显示定义拷贝构造函数,以完整地拷贝对象的所有数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++是一种通用的高级编程语言,它支持面向对象编程和基于类的编程范式。下面是一些关于C++基础语法和面向对象编程的重要概念: 1. 数据类型:C++提供了多种数据类型,包括整数类型(int,long等),浮点数类型(float,double等),字符类型(char),布尔类型(bool)等。 2. 变量和常量:在C++中,可以使用关键字来声明和定义变量。变量是用于存储数据的容器,在使用之前需要先声明其类型。常量是不可修改的值,可以使用关键字const来声明。 3. 控制流语句:C++提供了多种控制流语句,包括条件语句(if-else语句,switch语句),循环语句(for循环,while循环,do-while循环)等。这些语句允许根据条件执行不同的代码块或者重复执行一段代码。 4. 函数:函数是完成特定任务的代码块,可以在程序中多次调用。C++中的函数可以有参数和返回值。函数的参数用于接收传入的值,返回值用于向调用者返回结果。 5. 数组:数组是一种用于存储相同类型数据的集合。在C++中,可以使用方括号([])来声明和访问数组。数组的元素可以通过索引进行访问,索引从0开始。 6. 类和对象:C++支持面向对象编程,其中类是一种自定义数据类型,用于封装数据和函数。类中的数据成员表示对象的属性,函数成员表示对象的行为。对象是类的实例,可以通过创建对象来访问类中的成员。 7. 继承和多态:C++中的继承允许一个类从另一个类派生,从而继承其属性和方法。派生类可以添加额外的属性和方法,也可以重写基类中的方法。多态性允许使用基类指针或引用来调用派生类的方法。 以上是C++基础语法和面向对象编程的一些重要概念。掌握这些概念可以帮助你编写更加灵活和可扩展的C++程序。如果你有具体的问题或者需要更深入的讨论,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值