C++类内存管理

178 阅读3分钟

#一、初始化列表

构造函数名称():属性(值),属性(值)...

    #include<iostream>
    using namespace std;
    
    class PerSon
 {
  public:
    int m_A;
 	int m_B;
 	int m_C;
 	PerSon(int a, int b, int c)
 	{
	m_A = a;
	m_B = b;
	m_C = c;
 	}
 	
 	//初始化列表 
 	//用途:也是用来初始化类中的属性
 	PerSon(int a,int b,int c) :m_A(a), m_B(b), m_C(c)
 	{
 	
 	}
  };
  
  
  void test01()
 {
 PerSon p1(10, 20, 30);
 cout << "m_A = " << p1.m_A << endl;
 cout << "m_B = " << p1.m_B << endl;
 cout << "m_C = " << p1.m_C << endl;
     
 }
 
 int main()
 {
 test01();
 return 0;
 }

##二、xeplicit防止进行隐式转换

  class MySring
   {
  public:
  	MySring(char * str)
    	{
    	
    	    
    	}
  	//xeplicit 关键字用途:防止隐式类型转换方式来初始化对象
 	explicit MySring(int len)
 	{
	m_Len = len;
 	}
    	int m_Len;
  	char * m_Str;
    };
    void test01()
  {
  	MySring str = "abc";
   	MySring str2 = 10; //有的用户认为 字符串长度是10,有的用户认为 字符串就是10 导致二义性
   	                   //加上explicit关键字 程序将报错 不允许进行转换
   	MySring str3(10);
   	MySring str4 = MySring(10);
   	
   }

三、动态创建对象

概念:根据需求来分配空间大小,1.为对象分配内存。2.调用构造函数来初始化这块内存。

1.C动态分配内存方法:malloc以及它的变种calloc和realloc。释放内存的free,这些函数是有效的、但是原始的,需要l程序员理解和小心使用。

  class Person
  {
      public:
      Person()
      {
      mAge=20;
      pName=(char *)malloc(strlen("Jorn")+1);
      strcpy(pName,"Jorn");
  }
  void Clean()
  {
      if(pName!=NULL)
      {
          free(pName);
      }
  }
  int mAge;
  char * pName;
  };
  int main()
  {
      //分配内存
      Person * person=(Person *)malloc(sizeof(Preson));
      if(Person==NULL)
      {
      return 0;
      }
      //调用初始化函数
      person->Init();
      //清理对象
      person->Clean();
      //释放person对象
      free(person);
      return EXIT_SUCCESS;
  }

问题:1)程序员必须确定对象长度

2)malloc返回一个void *指针,C++不允许将void *赋值给其他任何指针 必须强转

3)malloc可能申请失败,所以必须判断返回值来确保内存分配成功

4)用户在使用对象之前必须记住对他初始化,构造函数不能显示调用初始化(构造函数是由编译器调用),用户可能忘记调用初始化函数。

2.C++使用运算符new和delete,当使用new创建一个对象时,他就在堆里为对象分配内存并调用构造函数完成初始化。 new操作符能确定在调用构造函数之前内存分配是成功的,所以不用显示确定调用是否成功。

1、mollc和new区别

1)new delete 是一个运算符 malloc free 是一个库函数

2)malloc 返回值 void * new返回的是new出来的对象指针

3)malloc 需要判断是否开辟成功 而new内部做好了操作(内部会malloc数字在堆区,判断内存是否分配成功,调用构造函数)

4)malloc 不会调用构造函数 而new调用构造函数

5)malloc 对应释放是 free new对应释放时delete

  #include<iostream>
  using namespace std;
 class PgrSon
 {
 public:
 	PgrSon()
 	{
	cout << "PgrSon的默认构造函数调用" << endl;
 	}
 	PgrSon(int age)
  	{
	m_Age = age;
	cout << "PgrSon的有参构造函数调用" << endl;
 	}
 
 	PgrSon(const PgrSon & p)
 
  	{
	m_Age = p.m_Age;
	cout << "PgrSon拷贝函数调用" << endl;
  	}
 	~PgrSon()
 	{
 		cout << "PgrSon析构函数调用" << endl;
 	    
 	}
 	int m_Age;
 };
 
 void test01()
  {
 	//PgrSon p1; //开辟栈上
 	
 	//开辟到堆区
 	PgrSon * p1 = new PgrSon; 
 	PgrSon * p2 = new PgrSon(10);
  	PgrSon * p3 = new PgrSon(*p2);
  	
  	//释放new出来的对象
 	delete p1;
 	delete p2;
 	delete p3;
 }
 //注意事项 
 void test02()
 {
 	//不要用void * 去接受new出来的对象,原因是不能释放
 	void * p = new PgrSon;
 	delete p;
 }
 //利用new来创建数组
 void test03()
 {
 	int * pInt = new int[10];
 	char * pChar = new char[64];
   	//利用new在堆区创建数组,类中必须要存在默认构造函数,否则无法创建
   	PgrSon * pgrson = new PgrSon[10];
    //如果数组是在栈上开辟的,则可以指定利用那个构造函数来初始化对象
  	//PgrSon pgrson2[3] = { PgrSon(10),PgrSon(10),PgrSon(10) };
  	
  		//释放 
  		delete[] pgrson;
 }
  int main()
 {
 	test01();
 	return 0;
 }