【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握

一、new和delete 堆区空间操作

1、new和delete操作基本类型的空间

new与C语言中mallocdelete和C语言中free 作用基本相同

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第1张图片

 区别:

new 不用强制类型转换

new在申请空间的时候可以 初始化空间内容

2、 new申请基本类型的数组

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第2张图片

 3、new和delete操作类的空间

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第3张图片

 4、new申请操作对象数组

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第4张图片

 二、静态成员

1、概念

类的对象 拥有独立的 普通成员数据。

static 修饰的成员 叫 静态成员。

class Data
{
    int a;//普通成员数据
    static int a;//静态成员数据
    static void func()//静态成员函数
{
}
};

2、静态成员数据

static修饰的静态成员 属于类而不是对象(所有对象 共享 一份 静态成员数据)。

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第5张图片

实战案例:使用静态成员数据 统计对象的个数

#pragma warning(disable:4996)
#include
using namespace std;
class Data
{
public:
	int mA;//普通成员数据
	static int count;//静态成员数据
public:
	Data()
	{
		count++;
	}
	Data(int a)
	{
		mA = a;
		count++;
	}
	Data(const Data &ob)
	{
		count++;
	}
	~Data()
	{
		count--;
	}
};
//类外初始化
int Data::count = 0;
void test()
{

	Data ob1;
	Data ob2(10);
	Data ob3 = ob2;
	cout << "对象个数:" << Data::count << endl;//3
	{
		Data ob4;
		Data ob5;
		cout << "对象个数:" << Data::count << endl;//5
	}
	cout << "对象个数:" << Data::count << endl;//3
}
int main(int argc, char* argv[])
{
	test();
	return 0;
 }

 3、静态成员函数

静态成员函数直接通过类名称访问

静态成员函数内 只能操作静态成员数据,因为普通成员数据还没有空间。

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第6张图片

 三、单例模式

        单例模式可以保证结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。即单例模式的类 只能实例化 一个对象。

        核心:将构造函数私有化

#include 
using namespace std;
class SingleTon//单例模式
{
//构造私有化 防止实例化其他对象
private:
    SingleTon(){
    count=0;
    cout<<"构造"<printString("学历证明1");
    p1‐>printString("身份证明1");

    SingleTon *p2 =SingleTon::getSingleTon();
    p2‐>printString("学历证明2");
    p2‐>printString("身份证明2");
}

四、类的存储结构

        成员函数静态成员 是独立存储 是所有对象共享,不占类的空间。

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第7张图片

五、this指针

         this是一个隐藏的指针,可以在类的成员函数中使用,它可以用来指向调用对象。当一个对象的成员函数被调用时,编译器会隐式地传递该对象的地址作为 this 指针。

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第8张图片

        this 指针是一个特殊的指针,它指向当前对象的实例。每一个对象都能通过 this 指针来访问自己的地址。

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第9张图片

        this可以完成链式操作 

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第10张图片

六、const修饰成员函数 

        const 修饰成员函数为只读(该成员函数不允许对 成员数据 赋值mutable修饰的成员除外

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第11张图片

七、友元

        预知识:将数据和方法封装在一起 加以权限区分 用户只能通过公共方法 操作私有数据。(封装 性)

        定义:一个函数或者类 作为了另一个类的友元 那么这个函数或类 就可以直接访问 另一个类的私 有数据。应用:友元 主要用在运算符重载上

        友元语法:friend关键字只出现在声明处,其他类、类成员函数、全局函数都可声明为友元,友元函数不是类的成员,不带 this指针友元函数可访问对象任意成员属性,包括私有属性。

        现实生活中也可以很好地理解:比如你的家,有客厅,有你的卧室,那么你的客厅是Public的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元

1、普通全局函数 作为类的友元

【第三天】C++类和对象进阶指南:从堆区空间操作到友元的深度掌握_第12张图片

2、 类的某个成员函数 作为另一个类的友元

#pragma warning(disable:4996)
#include
#include 
using namespace std;
class room;//向前声明,只能说明类名称
class Frind
{
public:
	void visiting01(Room& room);
	void visiting02(Room& room);
};
class Room
{
	friend void goodGay::visiting02(Room &room);
private:
	string bedroom;//实例化对象
public:
	string livingroom;
public:
	Room(string bedroom,string livingroom)
	{
		this-> bedroom = bedroom;
		this-> livingroom = livingroom;
	}
};
void test()
{
	Room room("我的卧室", "我的客厅");
	Frind ob;
	ob.visiting01(room);
	ob.visiting02(room);
}
int main(int argc, char* argv[])
{
	test();
	return 0;
 }

void Frind::visiting01(Room& room)
{
	cout << "李四访问到" << room.livingroom << endl;
	//cout<<"李四访问到"<

 3、整个类作为 另一个类的友元

         这个类的所有成员函数 都可以访问另一个类的私有数据

#pragma warning(disable:4996)
#include
#include 
using namespace std;
class room;//向前声明,只能说明类名称
class Frind
{
public:
	void visiting01(Room& room);
	void visiting02(Room& room);
};
class Room
{
	friend class Frind;
private:
	string bedroom;//实例化对象
public:
	string livingroom;
public:
	Room(string bedroom,string livingroom)
	{
		this-> bedroom = bedroom;
		this-> livingroom = livingroom;
	}
};
void test()
{
	Room room("我的卧室", "我的客厅");
	Frind ob;
	ob.visiting01(room);
	ob.visiting02(room);
}
int main(int argc, char* argv[])
{
	test();
	return 0;
 }

void Frind::visiting01(Room& room)
{
	cout << "李四访问到" << room.livingroom << endl;
	cout<<"李四访问到"<

4、案例

(1)遥控器的类

#include 
using namespace std;
class TV;
class Remote//遥控器类
{
private:
    TV *p;
public:
    Remote(TV *p);
    void offOrOn(void);//开关
    void upVolume(void);//音量
    void downVolume(void);
    void upChannel(void);//频道
    void downChannel(void);

    void showTv(void);
    void setChannel(int channel);
};
class TV
{
    friend void Remote::setChannel(int channel);
    enum{OFF, ON};
    enum{minVol, maxVol=10};
    enum{minChan, maxChan=25};
private:
    int state;
    int volume;
    int channel;
public:
    TV()
    {
        state = OFF;
        volume = minVol;
        channel = minChan;
    }
    void offOrOn(void);
    void upVolume(void);
    void downVolume(void);

    void upChannel(void);
    void downChannel(void);
    void showTv(void);
    };
int main(int argc, char *argv[])
{
    //实例化一个电视机
    TV tv;
    Remote re(&tv);
    re.offOrOn();
    re.upVolume();
    re.upVolume();
    re.upVolume();
    re.setChannel(20);
    re.showTv();
    return 0;
}
void TV::offOrOn()
{
    state = (state==OFF?ON:OFF);
    return;
}
void TV::upVolume()
{
    if(volume == maxVol)
    {
        cout<<"音量已经最大了"<p = p;
}
void Remote::offOrOn()
{
    p‐>offOrOn();
}

void Remote::upVolume()
{
    p‐>upVolume();
}
void Remote::downVolume()
{
    p‐>downVolume();
}

void Remote::upChannel()
{
    p‐>upChannel();
}

void Remote::downChannel()
{
    p‐>downChannel();
}

void Remote::showTv()
{
    p‐>showTv();
}
void Remote::setChannel(int channel)
{
    p‐>channel = channel;
}

(2)动态数组类

        根据数据大小动态增减空间。

array.h

#ifndef ARRAY_H
#define ARRAY_H
class Array
{
private:
    int *arr;//存放首元素地址
    int capacity;//容量
    int size;//大小
public:
    Array();
    Array(int capacity);
    Array(const Array &ob);
    ~Array();
    int getCapacity() const;
    int getSize() const;
    void printArray(void);
    //插入尾部元素
    void pushBack(int elem);
    //删除尾部元素
    void popBack(void);
    int &at(int pos);
};

#endif // ARRAY_H

array.cpp

#include "array.h"
#include
#include
using namespace std;
int Array::getCapacity() const
{
    return capacity;
}

int Array::getSize() const
{
    return size;
}

void Array::printArray()
{
    int i=0;
    for(i=0;i=size)
    {
        cout<<"访问违法内存"<capacity = capacity;
    size = 0;
    arr = new int[capacity];
    //空间清0
    memset(arr, 0, sizeof(int)*capacity);
}
Array::Array(const Array &ob)
{
    capacity = ob.capacity;
    size = ob.size;
    //深拷贝
    arr = new int[capacity];
    memcpy(arr, ob.arr, sizeof(int)*capacity);
}
Array::~Array()
{
    if(arr != NULL)
    {
        delete [] arr;
        arr = NULL;
    }
}

main.c

#include 
#include "array.h"
using namespace std;
int main(int argc, char *argv[])
{
    Array ob;
    cout<

你可能感兴趣的:(C/C++,c++,开发语言)