C++基礎學習筆記:類與動態記憶體分配
阿新 • • 發佈:2019-01-07
實現一個簡單的string類
user.h
//!時間:2017年9月11日(週一)上午 //!內容:類與動態記憶體分配 //!備註:Test類實現簡單的string功能 //!最後修改時間:NULL //user.cpp #define _CRTDBG_MAP_ALLOC//記憶體溢位檢測 #include <iostream> #include "Test.h" using namespace std; _CrtMemState s1, s2;//作為引數 int main() { //如果程式從開始加flag這一句,leaks就能自動呼叫而不寫 //適合用在多個退出點的情況 //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); //_CrtMemCheckpoint(&s1);//s1,s2之間可以具體定位 //_CrtMemCheckpoint(&s2); { Test one = "this is test!";//構造 Test two;//預設構造 two = one;//賦值運算子Test two = "test two.";//賦值運算子char* Test three(one);//拷貝構造 cin >> three; cout << one << two << three << endl; }//析構 system("pause"); _CrtDumpMemoryLeaks();//記憶體溢位檢測 return 0; }
類定義
//Test.h //#pragma once #ifndef _TEST_H #define _TEST_H #include <iostream> class Test { private: //C++11允許類內初始化 char *cStr; static int count;//定義一個計數變數,監測記憶體的申請和釋放次數 const static int CINLIMIT=100;//cin>>字串長度限制 public: Test(const char *s="");//建構函式:接受一個C字串 //拷貝與賦值需要逐個成員複製 Test(const Test&t);//拷貝構造:Test two(one); Test&operator=(const Test&t);//賦值運算子:two=one; //若沒有定義下面這一句,two="SOME"時,先把some通過建構函式隱式轉換為Test,再呼叫上面那句 Test&operator=(const char *s);//賦值運算子:two="some"; void Show();//測試輸出cStr與count; ~Test(); friend std::ostream&operator << (std::ostream &os, Test &t);//過載輸入輸出運算子 friend std::istream&operator >> (std::istream &is, Test &t); }; #endif
//Test.cpp #include "Test.h" int Test::count = 0; Test::Test(const char *s) { count++; //new匹配delete、new[]匹配delete[] cStr = new char[strlen(s) + 1];//申請一塊字串大小的記憶體 strcpy_s(cStr, strlen(s) + 1, s);//拷貝內容 //std::cout << "構造" << std::endl; } Test::Test(const Test&t) { count++; cStr = new char[strlen(t.cStr) + 1]; strcpy_s(cStr, strlen(t.cStr) + 1, t.cStr); //std::cout << "拷貝" << std::endl; } Test& Test::operator=(const Test&t) { //std::cout << "賦值Test" << std::endl; if (this == &t) return *this; delete[]cStr;//釋放舊的記憶體 cStr = new char[strlen(t.cStr) + 1];//申請新的記憶體 strcpy_s(cStr, strlen(t.cStr) + 1, t.cStr); return *this;//返回當前物件 } Test& Test::operator=(const char *s) { //std::cout << "賦值char*" << std::endl; delete[]cStr;//釋放舊的記憶體 cStr = new char[strlen(s) + 1];//申請新的記憶體 strcpy_s(cStr, strlen(s) + 1, s); return *this;//返回當前物件 } void Test::Show() { std::cout << cStr <<":"<<count<< std::endl; } Test::~Test() { delete[]cStr;//釋放記憶體 --count; std::cout << "當前count計數:" << count << std::endl; } std::ostream&operator << (std::ostream &os, Test &t) { os << t.cStr; return os; } std::istream&operator >> (std::istream &is, Test &t) { char temp[Test::CINLIMIT]; is.get(temp, Test::CINLIMIT); if (is)//檢測非法輸入 t = temp;//呼叫的賦值函式 while (is&&is.get() != '\n')//清空流:沒有到換行符,但還有大於CINLIMIT的輸入 { //std::cout << "++" << std::endl; continue; } return is; }