美文网首页
关于C++不了解的那些事

关于C++不了解的那些事

作者: 锦绣拾年 | 来源:发表于2021-04-27 23:10 被阅读0次

    关于C++不了解的那些事

    new & delete

    C++类实例化的两种方式:new和不new的区别 - Zopen的文章 - 知乎 https://zhuanlan.zhihu.com/p/62106872

    C++的new 和Java的new 很不一样,

    在Java中,所有对象都需要new 才能使用构造函数初始化,但是在C++中,new返回的是指针。

    A a;  // a存在栈上
    A* a = new a();  // a存在堆中
    
    C++中:
    
    Student  student(20) ;  //这里student是引用 对象分配在 栈空间中,这里只是我的理解
    
    Student *student = new  Student(20);  //这里student是指针,new Student(20)是分配在堆内存空间的
    
    vector<int> sd(20,0);
    vector<int> sd2 = vector<int>(20,0);//两者一样
    
    但是在Java中
    Student  student(20) ;  //注意:java中没有这样实例化对象的, 要想得到一个对象 必须要new出来.
    
    Student student ; //这个只是定义了一个引用 ,没有指向任何对象
    
    Student student = new Student(20);   //定义了一个引用,指向堆内存中的student对象
    ————————————————
    版权声明:本文为CSDN博主「tham_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/tham_/article/details/44906571
    

    → 右边这篇博文详细描述了C++和Java new的 区别,https://blog.csdn.net/tham_/article/details/44906571

    以上两种方式皆可实现类的实例化,有无new的区别在于:

    1 前者在栈中分配内存,后者在堆中分配内存

    2 动态内存分配会使对象的可控性增强

    3 大程序用new,小程序不加new,直接申请

    4new必须delete删除,不用new系统会自动回收内存

    • new创建类对象需要指针接收,一处初始化,多处使用
    • new创建类对象使用完需delete销毁
    • new创建对象直接使用堆空间,而局部不用new定义类对象则使用栈空间
    • new对象指针用途广泛,比如作为函数返回值、函数参数等
    • 频繁调用场合并不适合new,就像new申请和释放内存一样

    new[] delete[]

    Type* pointer = new Type[N];
    //...
    delete[] pointer;
    
    为什么delete不用给出数组长度?
    ①实际分配的内存块将多一个单元,用于头部本身。实际分配的块的大小被记录在头部size中。
    ②malloc返回的是空闲块的首地址,不是首地址。
    ③size字段是必要的,因为malloc控制的块不一定是连续的,这样就不能通过指针算数运算得到其大小。
    
    那也就证明了为什么当我们new[n]的时候,释放只需要写delete[],不用注明释放的大小的原因了。每次在释放的时候,会先查看释放的块的头部信息,其中就记录了这个块的大小。
    ————————————————
    版权声明:本文为CSDN博主「ZWE7616175」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/ZWE7616175/article/details/80520232
    

    引用和指针

    指针可以为空,引用不可以为空。

    引用可以视为变量的别名。

    C++primer中对 对象的定义:对象是指一块能存储数据并具有某种类型的内存空间一个对象a,它有值和地址&a,运行程序时,计算机会为该对象分配存储空间,来存储该对象的值,我们通过该对象的地址,来访问存储空间中的值指针p也是对象,它同样有地址&p和存储的值p,只不过,p存储的数据类型是数据的地址。如果我们要以p中存储的数据为地址,来访问对象的值,则要在p前加解引用操作符"*",即*p。
    int a,b,*p,&r=a;//正确
    r=3;//正确:等价于a=3
    int &rr;//出错:引用必须初始化
    p=&a;//正确:p中存储a的地址,即p指向a
    *p=4;//正确:p中存的是a的地址,对a所对应的存储空间存入值4
    p=&b//正确:p可以多次赋值,p存储b的地址
    
    作者:匿名用户
    链接:https://www.zhihu.com/question/37608201/answer/72766337
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    Class Object
    {// 实现省略,只需要知道我们在这里声明了一个类,在下面我们要将这个类的对象作为
     // 函数参数类型来使用};
    void fun1(Object obj)
    {
         // 此函数声明中,obj是值传递,会产生一个临时对象
    }
    void fun2(Object &obj)
    {
        // 我们不用检查obj是否为空,同时,使用引用传递,可以避免临时对象
    }
    int xiaoming = 1;
    int &refence_mingming = xiaoming;
    作者:nkaifang
    链接:https://www.zhihu.com/question/37608201/answer/90293843
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    总结:
    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;//值传递,产生临时对象
        *c += 1;//传指针,正常+1,让指针所在位置的数+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: 每个键只能出现一次,主要用于一对一映射。map里所有数据都是有序的。

    由于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;//与上面的打印结果相同
        }
        // 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的区别 - 世间事无常的文章 - 知乎 https://zhuanlan.zhihu.com/p/210458185

    1619103653(1).png

    相关文章

      网友评论

          本文标题:关于C++不了解的那些事

          本文链接:https://www.haomeiwen.com/subject/rulmrltx.html