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

这篇博客详细介绍了C++中的类与对象,包括赋值运算符重载、深拷贝与浅拷贝的概念与区别。此外,还探讨了友元的作用、分类及其代码实现,以及const限定符的多种应用。文章进一步讲解了static限定符的本质、使用规则和静态成员变量,并提到了内联函数的优化原理和注意事项。最后,讨论了运算符重载的策略,包括成员函数和友元函数两种方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

赋值运算符重载函数

类名& 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.	类型			语法				作用
1	const指针		类型* 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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值