關(guān)于C++不了解的那些事
new & delete
C++類實(shí)例化的兩種方式:new和不new的區(qū)別 - Zopen的文章 - 知乎 https://zhuanlan.zhihu.com/p/62106872
C++的new 和Java的new 很不一樣,
在Java中,所有對象都需要new 才能使用構(gòu)造函數(shù)初始化,但是在C++中,new返回的是指針。
A a; // a存在棧上
A* a = new a(); // a存在堆中
C++中:
Student student(20) ; //這里student是引用 對象分配在 ??臻g中,這里只是我的理解
Student *student = new Student(20); //這里student是指針,new Student(20)是分配在堆內(nèi)存空間的
vector<int> sd(20,0);
vector<int> sd2 = vector<int>(20,0);//兩者一樣
但是在Java中
Student student(20) ; //注意:java中沒有這樣實(shí)例化對象的, 要想得到一個對象 必須要new出來.
Student student ; //這個只是定義了一個引用 ,沒有指向任何對象
Student student = new Student(20); //定義了一個引用,指向堆內(nèi)存中的student對象
————————————————
版權(quán)聲明:本文為CSDN博主「tham_」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/tham_/article/details/44906571
→ 右邊這篇博文詳細(xì)描述了C++和Java new的 區(qū)別,https://blog.csdn.net/tham_/article/details/44906571
以上兩種方式皆可實(shí)現(xiàn)類的實(shí)例化,有無new的區(qū)別在于:
1 前者在棧中分配內(nèi)存,后者在堆中分配內(nèi)存
2 動態(tài)內(nèi)存分配會使對象的可控性增強(qiáng)
3 大程序用new,小程序不加new,直接申請
4new必須delete刪除,不用new系統(tǒng)會自動回收內(nèi)存
- new創(chuàng)建類對象需要指針接收,一處初始化,多處使用
- new創(chuàng)建類對象使用完需delete銷毀
- new創(chuàng)建對象直接使用堆空間,而局部不用new定義類對象則使用棧空間
- new對象指針用途廣泛,比如作為函數(shù)返回值、函數(shù)參數(shù)等
- 頻繁調(diào)用場合并不適合new,就像new申請和釋放內(nèi)存一樣
new[] delete[]
Type* pointer = new Type[N];
//...
delete[] pointer;
為什么delete不用給出數(shù)組長度?
①實(shí)際分配的內(nèi)存塊將多一個單元,用于頭部本身。實(shí)際分配的塊的大小被記錄在頭部size中。
②malloc返回的是空閑塊的首地址,不是首地址。
③size字段是必要的,因?yàn)閙alloc控制的塊不一定是連續(xù)的,這樣就不能通過指針?biāo)銛?shù)運(yùn)算得到其大小。
那也就證明了為什么當(dāng)我們new[n]的時候,釋放只需要寫delete[],不用注明釋放的大小的原因了。每次在釋放的時候,會先查看釋放的塊的頭部信息,其中就記錄了這個塊的大小。
————————————————
版權(quán)聲明:本文為CSDN博主「ZWE7616175」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/ZWE7616175/article/details/80520232
引用和指針
指針可以為空,引用不可以為空。
引用可以視為變量的別名。
C++primer中對 對象的定義:對象是指一塊能存儲數(shù)據(jù)并具有某種類型的內(nèi)存空間一個對象a,它有值和地址&a,運(yùn)行程序時,計(jì)算機(jī)會為該對象分配存儲空間,來存儲該對象的值,我們通過該對象的地址,來訪問存儲空間中的值指針p也是對象,它同樣有地址&p和存儲的值p,只不過,p存儲的數(shù)據(jù)類型是數(shù)據(jù)的地址。如果我們要以p中存儲的數(shù)據(jù)為地址,來訪問對象的值,則要在p前加解引用操作符"*",即*p。
int a,b,*p,&r=a;//正確
r=3;//正確:等價(jià)于a=3
int &rr;//出錯:引用必須初始化
p=&a;//正確:p中存儲a的地址,即p指向a
*p=4;//正確:p中存的是a的地址,對a所對應(yīng)的存儲空間存入值4
p=&b//正確:p可以多次賦值,p存儲b的地址
作者:匿名用戶
鏈接:https://www.zhihu.com/question/37608201/answer/72766337
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
Class Object
{// 實(shí)現(xiàn)省略,只需要知道我們在這里聲明了一個類,在下面我們要將這個類的對象作為
// 函數(shù)參數(shù)類型來使用};
void fun1(Object obj)
{
// 此函數(shù)聲明中,obj是值傳遞,會產(chǎn)生一個臨時對象
}
void fun2(Object &obj)
{
// 我們不用檢查obj是否為空,同時,使用引用傳遞,可以避免臨時對象
}
int xiaoming = 1;
int &refence_mingming = xiaoming;
作者:nkaifang
鏈接:https://www.zhihu.com/question/37608201/answer/90293843
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
總結(jié):
int *p =&a;//這里都是地址
*p=4//這里是值
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void add(int &a,int b,int* c){//第三個是指針,指針的值是地址,因此要傳一個地址
a += 1;//傳引用,正常+1
b += 1;//值傳遞,產(chǎn)生臨時對象
*c += 1;//傳指針,正常+1,讓指針?biāo)谖恢玫臄?shù)+1
cout << a << b << *c << endl;
cout << a + b + *c << endl;
}
int main(){
int a = 1;
int b = 3;
int c = 5;
cout << "origin" << endl;
cout << a << b << c << endl;
cout << "res" << endl;
add(a, b, &c);// int*p=&a
cout << a << b << c << endl;
cout << a + b + c << endl;
return 0;
}
打印輸出
origin
135
res
246
12
236
11
容器
一文理解C++常見容器用法 - wayneYM的文章 - 知乎 https://zhuanlan.zhihu.com/p/226014048
map
map: 每個鍵只能出現(xiàn)一次,主要用于一對一映射。map里所有數(shù)據(jù)都是有序的。
由于map中的元素不能排序,如果需要排序則可以把map賦值給vector。
判斷有無在map的key里
if (mymap.find(key) == mymap.end())
cout << "沒有這個key" << endl;
if (mymap.count(key) == 0)
cout << "no this key" << endl;
#include <iostream>
#include <vector>
#include <map>
#include <utility>
#include <algorithm>
using namespace std;
bool cmp(pair<string,int> &a,pair<string,int> &c){
return a.second<c.second;//從小到大排序
}
int main()
{
map<string,int> now = {{"res",6},{"oppp",2},{"test",9},{"ee",10}};
// cout<<"-=-=-=-="<<endl;
for(map<string,int>::iterator it=now.begin();it!=now.end();it++){
cout<<it->first<<"\t"<<it->second<<endl;
cout<<(*it).first<<"\t"<<(*it).second<<endl;//與上面的打印結(jié)果相同
}
// cout<<"-=-=-=-="<<endl;
map<string, int>::iterator iter;
iter = now.find("res");
if (iter != now.end())
{
cout <<"Find, the value is "<< iter->second << endl;
}
vector<pair<string,int>> op (now.begin(),now.end());
sort(op.begin(),op.end(),cmp);
for(int i=0;i<op.size();i++){
cout<<op[i].first<<op[i].second<<endl;
}
//cout << "Hello World"<<endl;
return 0;
}
map unorder_map
map和unordered_map的區(qū)別 - 世間事無常的文章 - 知乎 https://zhuanlan.zhihu.com/p/210458185
