有時需要在堆中創建對象,禁止在棧中去創建,
1 可以將析構函數定義爲private成員
2 建立static函數成員去delete這個堆空間
/* Human.h */
#include <string>
/*
* 爲了禁止某些類在棧中創建,措施之一是將析構函數定義爲private
* 這樣在函數使用完對象,並對其銷燬時將出現錯誤,因爲不能在外部調用析構函數
* 這種方式,堆內也是不可調用析構函數,delete也不可以使用, 導致內存泄露
* 可以定義一個靜態函數,去delete這個堆空間
*/
/*此類中存在指針成員*/
class Human
{
private:
char* name; //指針指向一塊內存空間,要實現深複製防止兩個對象的指針指向同一個內存,非常危險
~Human();
/*public類外可訪問*/
public:
Human(const char* initString); //變量若不允許函數修改,最好定義成const變量
/*複製構造函數(實現深複製), 參數爲對象,爲個不淺複製對象,用引用或指針的方式傳參*/
Human(const Human& Source);
static void destoryInstance(Human* obj)
{
delete obj; //釋放堆空間
}
};
/*Human.cpp*/
#include <iostream>
#include <string>
#include <string.h>
#include "Human.h"
Human::Human(const char* initString)
{
std::cout << "1 call Human()" << std::endl;
name = new char[strlen(initString) + 1];
}
Human::Human(const Human& source)
{
std::cout << "2 call copy constructor function " << std::endl;
name = new char[strlen(source.name) + 1]; //重新分配一個內存空間,保證兩個對象的指針成員不指向同一個內存空間
strncpy_s(name, strlen(source.name) + 1, source.name, strlen(source.name) + 1);
}
/*析構函數(對象被銷燬時被調用,類只有一個析構函數*/
Human::~Human()
{
std::cout << "3 call ~Human()" << std::endl;
delete name;
}
#include <iostream>
#include "Human.h"
int main()
{
Human* man = new Human("aaaa"); //此處第一次調用構造函數
//delete man; //失敗,導致內存泄露
man->destoryInstance(man);
return 0;
}
輸出:
1 call Human()
3 call ~Human()