python网站开发集成环境,wap网站建设免费,做网站ssl证书必须要吗,crm系统是干什么的一.内部类
1.如果一个类定义在另一个类的内部#xff0c;这个内部类就叫做内部类。内部类是一个独立的类#xff0c;跟定义在全局相比#xff0c;他只是受外部类类域限制和访问限定符限制#xff0c;所以外部类定义的对象中不包含内部类。 2.内部类默认是外部类的友元类。…一.内部类
1.如果一个类定义在另一个类的内部这个内部类就叫做内部类。内部类是一个独立的类跟定义在全局相比他只是受外部类类域限制和访问限定符限制所以外部类定义的对象中不包含内部类。 2.内部类默认是外部类的友元类。 3.内部类本质也是一种封装当A类跟B类紧密关联A类实现出来主要就是给B类使用那么可以考虑把A类设计为B的内部类如果放到private/protected位置那么A类就是B类的专属内部类其他地方都用不了。
比如下面这个例子 这两种写法效果是一样的B此时就是A的内部类。
二.匿名对象
匿名对象当下的阶段可能没有太大的作用但在模板之后便会有显著作用了它的特点如下
1.用类型(实参) 定义出来的对象叫做匿名对象相比之前我们定义的 类型 对象名(实参) 定义出来的叫有名对象。 2.匿名对象生命周期只在当前一行一般临时定义一个对象当前用一下即可就可以定义匿名对象。
牛客网上的一道题如下日期累加_牛客题霸_牛客网 (nowcoder.com)
这里就可以使用下匿名对象来解决这道题(虽然效果不是太明显了)
#include iostream
#include assert.h
using namespace std;class Date {public:Date(): _year(2024),_month(9),_day(13) {int m 0;int n 0;cin m;while (m--) {cin _year _month _day n;*this n;DatePrint(*this);}}int GetMonthDay() {assert(_month 12 || _month 0);static int arr[13] { -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };if (_month 2 ((_year % 4 0 _year % 100 ! 0) || _year % 400 0)) {return 29;}return arr[_month];}Date operator-(int i) {if (i 0) {return *this -i;}_day - i;while (_day 0) {_day GetMonthDay();--_month;if (_month 0) {--_year;_month 12;}}return *this;}Date operator(int i) {if (i 0) {return *this - -i;}_day i;while (_day GetMonthDay()) {_day - GetMonthDay();_month;if (_month 13) {_year;_month 1;}}return *this;}void DatePrint(const Date d) {if(d._month 10 d._day 10)cout d._year - d._month - d._day endl;else if(d._month 10 d._day 10)cout d._year - 0 d._month - d._day endl;else if(d._month 10 d._day 10)cout d._year - d._month - 0 d._day endl;else if(d._month 10 d._day 10)cout d._year - 0 d._month - d._day endl;elsecout d._year - 0 d._month - 0 d._day endl;;}private:int _year;int _month;int _day;
};
int main() {Date();return 0;
}
我们可以直接通过匿名对象来调用其构造函数直接完成所有函数的调用来实现这道题目(写的有些糅杂还请见谅)。
三.C/C内存管理
3.1new与delete
我们在学习C的时候已经知道通过使用malloc/realloc/calloc/free函数来管理我们开辟的动态内存。在C中我们将介绍两个新的操作符new和delete来进行动态内存管理。基本使用方式如下
void Test()
{// 动态申请一个int类型的空间int* ptr4 new int;// 动态申请一个int类型的空间并初始化为10int* ptr5 new int(10);// 动态申请10个int类型的空间int* ptr6 new int[3];delete ptr4;delete ptr5;delete[] ptr6;
}申请和释放单个元素的空间使用new和delete操作符申请和释放连续的空间使用 new[]和delete[]new与delete在处理内置类型时与malloc/free别无差异当开辟的是自定义类型时new与delete会在开辟的时候调用自定义类的构造和析构函数注意匹配起来使用否则会出现未定义行为比如我们用下面这个例子来解释
char* p new char[100];
delete p;
当你使用new[]来动态分配内存如果你使用错误的delete(而不是delete[])来释放这段内存(如delete p),虽然它可能不会立即出现问题,但实际上是未定义行为。
在使用delete p来释放使用new[]分配的内存时C 标准明确规定这是未定义行为。然而在实践中对于简单类型如char、int等原始数据类型由于它们没有复杂的构造函数和析构函数,delete没有明显的副作用。系统仅仅会释放内存空间这与free的行为类似。
所以在使用内置类型这种简单的类型时一般不会出现问题。一旦使用自定义类型时编译器就会因无法正确处理所有对象的析构和内存释放而导致报错。
3.2operator new与operator delete
new和delete是用户进行动态内存申请和释放的操作符operator new 和operator delete是 系统提供的全局函数new在底层调用operator new全局函数来申请空间delete在底层通过 operator delete全局函数来释放空间。
/*
operator new该函数实际通过malloc来申请空间当malloc申请空间成功时直接返回申请空间
失败尝试执行空 间不足应对措施如果改应对措施用户设置了则继续申请否
则抛异常。
*/
void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{// try to allocate size bytesvoid* p;while ((p malloc(size)) 0)if (_callnewh(size) 0){// report no memory// 如果申请内存失败了这里会抛出bad_alloc 类型异常static const std::bad_alloc nomem;_RAISE(nomem);}return (p);
}
/*
operator delete: 该函数最终是通过free来释放空间的
*/
void operator delete(void* pUserData)
{_CrtMemBlockHeader* pHead;RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));if (pUserData NULL)return;_mlock(_HEAP_LOCK); /* block other threads */__TRY/* get a pointer to memory block header */pHead pHdr(pUserData);/* verify block type */_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead-nBlockUse));_free_dbg(pUserData, pHead-nBlockUse);__FINALLY_munlock(_HEAP_LOCK); /* release other threads */__END_TRY_FINALLYreturn;
}
通过上述两个全局函数的实现知道operator new实际也是通过malloc来申请空间如果 malloc申请空间成功就直接返回否则执行用户提供的空间不足应对措施如果用户提供该措施 就继续申请否则就抛异常。operator delete最终是通过free来释放空间的。
3.3new和delete的实现原理
3.3.1内置类型
如果申请的是内置类型的空间new和mallocdelete和free基本类似不同的地方是 new/delete申请和释放的是单个元素的空间new[]和delete[]申请的是连续空间而且new在申 请空间失败时会抛异常malloc会返回NULL。
3.3.2自定义类型
(1)new的原理 1. 调用operator new函数申请空间 2. 在申请的空间上执行构造函数完成对象的构造
(2)delete的原理 1. 在空间上执行析构函数完成对象中资源的清理工作 2. 调用operator delete函数释放对象的空间
(3)new T[N]的原理 1. 调用operator new[]函数在operator new[]中实际调用operator new函数完成N个对 象空间的申请 2. 在申请的空间上执行N次构造函数
(4)delete[]的原理 1. 在释放的对象空间上执行N次析构函数完成N个对象中资源的清理 2. 调用operator delete[]释放空间实际在operator delete[]中调用operator delete来释 放空间
3.4malloc/free和new/delete的区别
malloc/free和new/delete的共同点是都是从堆上申请空间并且需要用户手动释放。不同的地 方是1. malloc和free是函数new和delete是操作符 2. malloc申请的空间不会初始化new可以初始化 3. malloc申请空间时需要手动计算空间大小并传递new只需在其后跟上空间的类型即可 如果是多个对象[]中指定对象个数即可 4. malloc的返回值为void*, 在使用时必须强转new不需要因为new后跟的是空间的类型 5. malloc申请空间失败时返回的是NULL因此使用时必须判空new不需要但是new需 要捕获异常 6. 申请自定义类型对象时malloc/free只会开辟空间不会调用构造函数与析构函数而new 在申请空间后会调用构造函数完成对象的初始化delete在释放空间前会调用析构函数完成 空间中资源的清理释放