C++基础——类与对象(下)

来源:互联网 发布:eos m5 评价相机知乎 编辑:程序博客网 时间:2024/05/23 14:14

赋值运算符重载函数

类名& operater=(const 类名& 形参){// 赋值操作return *this;}

调用时机:

赋值

代码

Bill Bill::operator=(const Bill& b){price = b.price;      count = b.count;      discount = b.discount;      if(NULL != name){delete [] name;        name = NULL;      }

拷贝构造函数与赋值操作符的区别

拷贝构造函数:当一个已经存在的对象来初始化一个未曾存在的对象。
赋值操作符:当两个对象都已经存在。

深拷贝与浅拷贝

浅拷贝:只拷贝指针地址(引用)。
深拷贝:重现分配堆内存,拷贝指针指向内容(构造)。

友元

作用:

非成员函数访问类中的私有成员

分类

全局友元函数:将全局函数声明成友元函数
友元成员函数:类的提前引用声明,将一个函数声明为多个类的友元函数
友元类:将整个类声明为友元

特点

友元关系单向性
友元关系不可传递

代码

class Bill{friend void sum(Bill);friend void sum(Bill*);//friend void Bills::PrintAll();friend class Bills;。。。。。}

const限定符

本质:不可修改。

const 类型 变量 = 初始值;const 类型 对象;
类型 const 变量 = 初始值;类型 const 对象;
例:

const int size = 4;int const size = 4;
定义时必须初始化
全局作用域声明的const变量默认作用域是定义所在文件
const对象只能调用const成员函数

const与宏定义#define的区别

const宏定义#define编译器处理方式编译运行阶段使用预处理阶段展开/替换类型有具体的类型没有类型安全检查编译阶段会执行类型检查不做任何类型检查存储方式分配内存不分配内存

const与指针

No.类型语法作用1const指针类型* const 变量 = 初始值;指针指向地址不能改变2指向const对象的指针const 类型* 变量 = 初始值; 指针指向对象不能改变类型 const* 变量 = 初始值;3指向const对象的const指针const 类型* const 变量 = 初始值;指针指向地址和对象不能改变

const成员变量

1.不能在类声明中初始化const数据成员;
2.const成员变量只能在类构造函数的初始化列表中初始化;
3.如果使用const成员变量不能使用赋值运算符重载函数(不能被修改)。
class 类名{public:    类名(类型 形参):成员变量(形参){}private:    const 类型 成员变量;}

const位置与作用

const修饰位置作用变量变量不可修改,通常用来替代#define对象/实例对象的成员变量不可修改,只能调用const成员函数函数参数参数不能在函数内部修改,只作为入参函数返回值返回的结果不能被修改,常用于字符串成员变量只能在初始化列表中初始化成员函数不改变成员变量
PS:只要能够使用const,尽量使用const。

static限定符

本质:

生存周期:整个程序的生存周期。
作用域:属于类,不属于对象。

声明

class 类名{  static 返回类型 函数(形参列表);};

定义

返回类型 类名::函数(形参列表){  函数体;}

调用

类名::函数(实参列表);

规则

static只能用于类的声明中,定义不能标示为static。
非静态是可以访问静态的变量和函数
静态成员函数可以设置private,public,protected访问权限

禁忌

静态成员函数不能访问非静态函数或者变量
静态成员函数不能使用this关键字
静态成员函数不能使用cv限定符(const与virtual)

PS:因为静态成员函数是属于类而不是某个对象。

静态成员变量

语法:

1.在类定义中声明,但是在类实现中初始化。
2.在声明时需要指定关键字static,但是实现时不需要指定static。
3.对象的大小不包含静态成员变量
因为静态成员变量是属于类而不是某个对象。静态成员变量所有类的对象/实例共享。

static修饰位置与其作用

static修饰位置作用变量静态变量函数只源文件内部使用的函数成员变量对象共享变量成员函数类提供的函数,或者作为静态成员对象的接口

const static限定符

变量类型声明位置一般成员变量在构造函数初始化列表中初始化const成员常量必须在构造函数初始化列表中初始化static成员变量必须在类外初始化static const/const static成员变量(必须是整形)变量声明处或者类外初始化

代码例子

#include <iostream>using std::cout;using std::endl;class StaticConstTest{public:    void print(){        cout << test1 << " " << test2 << endl;    }private:    static const int test1 = 1;    static const int test2;};/* static */ const int StaticConstTest::test2 = 2;int main(){    StaticConstTest sct;    sct.print();}

函数的调用优化——内联

本质

内联函数的代码直接替换函数调用,省去函数调用的开销。

条件

一般用在代码比较简单的函数。

语法

关键字inline必须与函数实现/定义体放在一起才能使函数成为内联,将inline放在函数声明前面不起任何作用。
定义在类声明之中的成员函数将自动地成为内联函数。

慎用内联

如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。
不要随便地将构造函数和析构函数的定义体放在类声明中。

代码

inline /*friend*/ bool operator==(const Rational& left,const Rational& right){return &left == &right or left.numer*right.denom == left.denom*right.numer;}

运算符重载

本质

函数重载

成员函数运算符重载

返回值类型 operator 运算符(参数){  函数体}

友元函数运算符重载

friend 返回值类型 operator 运算符(形参列表) {   函数体 }

规则

五个不能重载的运算符:成员运算符.、指针运算符*、作用域运算符::、sizeof、条件运算符?:
不允许用户自定义新的运算符,只能对已有的运算符进行重载
重载运算符不允许改变运算符原操作数的个数
重载运算符不能改变运算符的优先级
重载运算符函数不能有默认的参数,会导致参数个数不匹配

代码

/*friend*/ ostream& operator<<(ostream& out,const Complex& c){out << c.real << "+" << c.imag << "i" << endl;return out;}
Complex Complex::operator+(const Complex& other)const{Complex res;res.real = other.real + this->real;res.imag = other.imag + this->imag;return res;}//用构造函数Rational(int n):numer(n),denom(1){}
inline /*friend*/ bool operator==(const Rational& left,const Rational& right){return &left == &right or left.numer*right.denom == left.denom*right.numer;}