zoukankan      html  css  js  c++  java
  • C++学习笔记之高级语法

    高级语法

    面向对象——类

    C++使用struct、class来定义一个类:

    • struct 的默认成员权限是public
    • class 的默认成员权限是private
    • 除此之外,二者基本无差别。

    struct 更适合看成是一个数据结构的实现体,class 更适合看成是一个对象的实现体。

    对象的属性

    C++没有类似于C#的属性,需要自己实现Get、Set方法,代码如下:

    class Test
    {
    public:
        Test(){}
        Test(int _m):_cm(_m){}
    
        int GetCm() const { return _cm; }
        void SetCm(int c)  { _cm=c;   }
     
    private:
        int _cm;
    };
    

    注:Get函数需要用const修饰为常函数,参考C++ 类class const修饰成员函数

    运算符重载

    运算符重载函数既可以声明为类的成员函数,也可以声明为所有类之外的全局函数,参考 C++学习27 用全局函数重载运算符

    • 将运算符重载函数声明为类的成员函数时,二元运算符的参数只有一个,一元运算符不需要参数。之所以少一个参数,是因为这个参数是隐含的。
    • 将运算符重载函数声明为全局函数时,二元操作符就需要两个参数,一元操作符需要一个参数,而且其中必须有一个参数是对象,好让编译器区分这是程序员自定义的运算符,防止程序员修改用于内置类型的运算符的性质。

    复合赋值操作符是指 += , *= , -= 这一类由基本算数运算符( + 、 - 、 * 、 / )或位运算符(| 、 & 、~等)加 = 号构成的运算符。它们把左右操作数进行相应运算后的结果赋值给左操作符, 复合赋值操作符的返回值,默认是左值。比如a += b;中的a。

    在进行复合赋值操作符重载定义的时候,需要注意,其返回值,应该为( * this)<类成员>或者第一个也就是左操作数<非成员函数>,参考 C++运算符重载

    //类成员函数方法实现运算符重载
    className & className::operator +=(className & right)
    {
        return (*this) = (*this) + right;
    }
    
    //全局函数方法实现运算符重载
    className& operator +=(className& left, className& right)
    {
        return left = left + right;
    }
    

    常用的运算符重载(类成员函数)定义如下:

    // 运算符重载
    className operator+(const className &c) const;
    className& operator+=(const className &c);
    className operator-(const className &c) const;
    className& operator-=(const className &c);
    className operator*(const className &c) const;
    className& operator*=(const className &c);
    className operator/(const className &c) const;
    className& operator/=(const className &c);
    
    bool operator==(const className &c) const;
    bool operator!=(const className &c) const;
    bool operator>(const className &c)  const;
    bool operator>=(const className &c) const;
    bool operator<(const className &c) const;
    bool operator<=(const className &c) const;
    
    // 前置和后置++
    className& operator++();   //前置++
    className operator++(int); //后置++
    className& operator--();   //前置--
    className operator--(int); //后置--
    
    //IO重载,全局函数
    friend ostream& operator<<(ostream& os, const className &x);
    friend istream& operator>>(istream& is, className &x);
    

    拷贝构造函数

    拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象,参考 C++ 拷贝构造函数

    拷贝构造函数通常用于:

    • 通过使用另一个同类型的对象来初始化新创建的对象。
    • 复制对象把它作为参数传递给函数。
    • 复制对象,并从函数返回这个对象。

    拷贝构造函数的最常见形式如下:

    classname (const classname &obj) {   // 构造函数的主体 }
    

    IO缓存

    C++ IO标准库 文件操作

    cin.ignore(numeric_limits<std::streamsize>::max(), '
    ');  // 清空缓存区脏数据
    

    头文件的重复包含问题

    方案1:使用宏来防止同一个文件被多次包含:

    #ifndef _SOMEFILE_H
    #define _SOMEFILE_H
    //头文件内容
    #endif
    

    优点:可移植性好;
    缺点:无法防止宏名重复,难以排错;

    方案2:使用编译器来防止同一个文件被多次包含:

    #pragma once
    //头文件内容
    

    优点:可以防止宏名重复,易排错;
    缺点:可移植性不好;

    总结:只考虑Windows系统可以用方案2,否则用方案1

    深拷贝与浅拷贝

    浅拷贝只拷贝指针地址,C++默认拷贝构造函数与赋值运算符重载都是浅拷贝;节省空间,但容易引发多次释。

    深拷贝重新分配堆内存,拷贝指针指向内容;浪费空间,但不会导致多次释放。

    兼有二者的优点:

    • 方案一:引用计数
    • 方案二:C++新标准的移动语义
    // 移动赋值运算符
    String& String::operator=(String&& rhs)noexcept
    {
    	if(this != &rhs)
    	{
    		delete[] m_data;
    		m_data = rhs.m_data;
    		rhs.m_data = NULL;
    	}
    	return *this;
    }
    
    // 移动构造函数
    String::String(String&& other)
    {
    	if (other.m_data != NULL)
    	{
    		// 资源让渡
    		m_data = other.m_data;
    		other.m_data = NULL;
    	}
    }
    
    //使用
    String s1("Hello");   
    String s2A(std::move(s1));              // 移动构造函数
    String s3A;                                      // 无参构造函数
    s3A = std::move(s2A);                    // 移动赋值运算符
    

    面向对象三大特性

    封装性:数据和代码捆绑在一起,避免外界干扰和不确定性访问,封装可以使得代码模块化
    继承性:让某种类型对象获得另一个类型对象的属性和方法,继承可以扩展已存在的代码
    多态性:同一事物表现出不同事物的能力,即向不同对象会产生不同的行为,多态的目的则是为了接口重用

  • 相关阅读:
    Vue 移动端向上滑动加载
    关于NPOI 判断Office 是否为空的操作
    定时任务的处理
    Web中线程与IIS线程池自动回收机制
    本地VS调试服务器 IIS 程序
    每天学点node系列-stream
    聊聊前端模块化开发
    位运算解决多标签问题【原创】
    <未来世界的幸存者> 读后感(现实篇和职业篇)【原创】
    Nest.js你学不会系列-初识Nest
  • 原文地址:https://www.cnblogs.com/timefiles/p/CppStudyNotesAdvancedGrammar.html
Copyright © 2011-2022 走看看