类定义(class definition)

类定义(class definition)

class以外的函数

  • 存在的一定是函数

  • 如果是class的函数,那么一定带有类名::function

  • 要么就是全局函数,函数名称不会带有class_name_function_name

非成员函数(无this)

示例代码:

inline complex
operator + (const complex& x, const complex& y)
{
return complex(real(x) + real(y), imag(x) + imag(y));
}

inline complex
operator + (const complex& x, double y)
{
return complex(real(x) + y, imag(y));
}

inline complex
operator + (double x, const complex& y)
{
return complex(x + real(y), imag(y));
}

上述的例子当中进行相加完成以后并没有一个object -> 所以返回的是一个value -> 所以在return的时候不能return by reference

临时对象 -> typename () -> 声明周期到下一行就结束了.使用这个声明方法可以声明temp object

示例代码:

#pragma once
/*
无指针的类,单一的类,不和其他类有关联的
*/
#ifndef __COMPLEX__ // guard 防卫式声明 -> 不要有重复的include动作
#define __COMPLEX__

/*
class head
class body
body内函数
body外函数
*/
// template<typename T>
class complex // class head
{
public:
complex (double r = 0, double i = 0) : re(r), im(i) { }
// complex () : re(0), im(0) { } 由于上一个构造器有默认值,所以这个构造函数和第一个冲突

complex& operator += (const complex&);
double real() const { return re; }
double imag() const { return im; }

private:
// 实部虚部类型
double re, im;

friend complex& __doapl(complex*, const complex&); // 函数声明 -> 友元函数可以直接获得private变量
};

inline complex& // 这里是接收端接收的形式
__doapl(complex* ths, const complex& r) {
// 自由取得private变量
ths->re += r.re; // 将第二参数的re加到第一参数上,所以第一参数会改变,第二参数不会改变
ths->im += r.im;
// 返回值是一个object
return *ths;
}

// 之所以设计成reference类型是因为考虑连续赋值情况 -> 如果是连等情况,那么返回值不可以是void
inline complex&
// 因为是内部函数,所以友complex::函数名称
complex::operator += (const complex& r)
{
/*
+=操作会将右数加到左数上
会将左数的指针传入函数
*/
return __doapl(this, r);
}

inline complex&
complex::operator += (const complex& r)
{
// 调用者就是this,这是一个指针. += 符号作用在左边的数,左边的数就是this. -> 编译器自动会传入c2的指针
// this在参数列不能写出但是在函数中可以使用
return __doapl(this, r);
}

// class body之外的各种定义
inline double
imag(const complex& x)
{
return x.imag();
}

inline double
real(const complex& x)
{
return x.real();
}

// 这里返回的不是reference,返回的是一个value
inline complex
operator + (const complex& x, const complex& y)
{
return complex(real(x) + real(y), imag(x) + imag(y));
}

inline complex
operator + (const complex& x, double y)
{
return complex(real(x) + y, imag(y));
}

inline complex
operator + (double x, const complex& y)
{
return complex(x + real(y), imag(y));
}

inline complex
operator + (const complex& x)
{
return x;
}

inline complex
operator - (const complex& x)
{
// 创建临时对象
return complex(-real(x), -imag(x));
}

inline bool
operator == (const complex& x, const complex& y)
{
return real(x) == real(y) && imag(x) == imag(y);
}

inline bool
operator != (const complex& x, const complex& y)
{
return real(x) != real(y) || imag(x) != imag(y);
}

// 共轭复数 -> 实部相等,虚部相反
inline complex
conj(const complex& x)
{
return complex(real(x), -imag(x));
}

#include <iostream>
ostream&
operator << (osteam& os, const complex& x)
{
return os << '(' << real(x) << ',' << imag(x) << ')';
}

#endif // __COMPLEX__

Stack(栈)、Heap(堆)

栈(Stack)

存在于某作用域(scope)的一块内存空间.调用函数时,函数本身会形成一个stack来放置所接收的参数以及返回地址 -> 函数本体内声明的任何变量所使用的内存块都取自上诉的stack

堆(Heap)

system heap由操作系统提供的一块global内存空间.程序可动态分配.

使用new的方式从堆中取得的任何东西都必须手动释放掉 -> stack离开了作用域会自动调用析构函数释放掉

static local objects

stack对象前加static关键字.那么该对象在离开作用域的时候还会存在.他的析构函数会在程序结束时调用

global objects的声明周期

生命周期也是在程序解释之后才会结束

new进行的三步操作

示例代码:

Complex* pc = new Complex(1, 2);

//以下是编译器转化上一句代码的行为
// 步骤1
void* mem = operator new(sizeof(Complex)); // 这个方法去调用c当中的malloc(n)进行内存分配
// 步骤2,将第一个动作的指针转型
pc = static_cast<Complex*>(mem);
// 再调用Complex的构造函数 -> 通过步骤2得到的指针 -> 谁调用谁是this
pc->Complex::Complex(1, 2);

delete进行的几个操作

示例代码:

String* ps = new String("Hello");

delete ps;

// 编译器行为
String::~String(ps); // 先调用析构函数
operator delete(ps);
// 内部调用free
free(ps);

new的时候用数组那么delete的时候就需要用数组

array new一定要搭配array delete

示例代码:

String* p = new String[3];

delete[] p; // 因为上面创建了三个String对象,所以应该调用三次析构函数

String* p = new String[3];

delete p; // 这样析构函数只被唤起了一次
 
posted @   俊king  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2022-03-30 2022/03/29 Mac布置项目环境进行包管理
2021-03-30 计算机系统概论
2021-03-30 3.29Java流程控制语句之循环结构
点击右上角即可分享
微信分享提示