自主的内存回收机制:1、手动开辟 2、系统释放
栈上的内存:1、系统开辟 2、系统释放
堆上的内存:1、手动开辟 2、手动释放
对象的生存:1、开辟内存 2、调用构造函数
对象的销毁:1、调用析构函数 2、释放内存
int *p=new int 堆上开辟内存,把操作的所有权限交给栈上的变量,栈上的内存系统释放,而堆上的内存需要手动释放
可以把权限交给类对象,对象销毁时可以先调用析构函数,释放堆上的内存再释放对象内存
栈上的一个成员对象,对象有一个指针指向一个堆内存,栈上的对象生存周期到了之后要销毁,系统自动清理,不仅要释放栈的空间,在释放栈空间之前,对所占的资源进行释放。可以在析构函数中做 delete
#include<iostream>
#include<algorithm>
using namespace std;
#include<string.h>
class Test
{
public:
Test(int a) :ma(a)
{}
void Show()
{
std::cout << ma << std::endl;
}
private:
int ma;
};
class SmartPtr
{
public:
SmartPtr(Test* p) :ptr(p){}
~SmartPtr()
{
delete ptr;
ptr = NULL;
}
Test* operator->()//->重载函数
{
return ptr;
}
private:
Test* ptr;
};
int main()
{
Test* ptest = new Test(10);
ptest->Show();
delete ptest;
SmartPtr sp2 = new Test(20);//拷贝构造
sp2->Show();
//sp2.operator->() /// Test* ptmp// ptmp->Show();
return 0;
}
继承
继承的目的:为了代码复用
class people
class Student : public people
people类派生Student类
Student类继承people类
类标识 派生类类名:继承方式 基类名
派生类继承了基类的什么东西?
继承了普通成员变量 也能继承静态成员变量普通函数,并且构造函数
继承了普通成员方法 也能继承静态成员方法
构造函数和析构函数不能被继承:因为构造函数名必须和类名相同,如果继承下来就变成普通函数,并且构造函数也没有返回值,所以不能继承构造函数
继承方式:public protected private
基类中不同访问限定符的成员以不同的继承方式,继承后在派生类中的访问限定
派生类的内存布局:
派生类对象生成
1、开辟内存(基类+派生类)内存
2、对象空间初始化(1、系统调用基类的构造函数,默认调用默认的构造函数2、系统调用派生类的构造函数)
class Base
{
public:
Base(int a) :ma(a){}
protected:
int ma;
};
class Derive:public Base
{
public:
Derive(int b) :mb(b), Base(b)
{
}
private:
int mb;
};
int main()
{
Derive d(10);
return 0;
}
#if 0
class A//基类
{
public:
A(){}
public:
int ma;
protected:
int mb;
private:
int mc;
};
class B : private A
{
//mb protected
//mb private
//mc 不可见
public:
B(){}
void Show()
{
std::cout << mb << std::endl;
}
};
class C :public B
{
public:
C(){}
void Show()
{
//std::cout << mb << std::endl;
}
};
int main()
{
B b;
C c;
//std::cout << b.mb << std::endl;
b.Show();
c.Show();
/*std::cout << sizeof(A) << std::endl;
std::cout << sizeof(B) << std::endl;*/
return 0;
}