• c++学习


    #include<iostream>
    
    int main()
    {
        std::cout<<"test 
    ";
        int sjk;
        std::cin>>sjk;
        std::cout<<sjk;
        return 0;
    }
    #include <iostream>
    //using std::cout;
    //using std::endl;
    
    using namespace std;
    
    int main()
    {
        cout<<"test 
    ";
        cout<<endl;
        
        
        return 0;
    }

    命名空间冲突问题

    #include <iostream>
    //using namespace std;
    
    namespace a{
        int a=1;
    }
    
    namespace b{
        int a=2;
    }
    
    
    int main()
    {
        //int a=3;
        using namespace a;
        using namespace b;
        std::cout<<a<<"|"<<a::a<<"|"<<b::a<<std::endl;
        
        return 0;
    }

    函数应用

    #include <iostream>
    using namespace std;
    
    int sum(int a, int b)
    {
        return a+b;
    }
    
    int main()
    {
        int a, b;
        
        cin>>a;
        cin>>b;
        
        cout<<"a+b="<<sum(a,b);
        
        return 0;
    }

    函数的声明与定义

    #include <iostream>
    using namespace std;
    
    //函数声明
    //int sum(int a, int b);
    int sum(int, int); //参数名可以省略
    
    int main()
    {
        int a, b;
        
        cin>>a;
        cin>>b;
        
        cout<<"a+b="<<sum(a,b);
        
        return 0;
    }
    
    //函数定义
    int sum(int a, int b)
    {
        return a+b;
    }
    #include <iostream>
    using namespace std;
    
    
    void a();
    void b();
    
    void a()
    {
        cout<<"a 
    ";
        b();
    }
    
    void b()
    {
        cout<<"b 
    ";
        a();
    }
    
    
    int main()
    {
        a();
    
        return 0;
    }

    变量范围

    #include <iostream>
    using namespace std;
    
    int x,y;//全局变量对任何函数都有效
    
    void change()
    {
        x=100;
    }
    
    int main()
    {
        change();
        cout<<x;
        
        return 0;
    }

    款字符型

    #include <iostream>
    #include <locale>
    
    using namespace std;
    
    
    int main()
    {
    
        setlocale(LC_ALL, "chs");
        wchar_t wc[] = L"";
        wcout<<wc;
        
        
        return 0;
    }
    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    
    int main()
    {
        double a=1.32545488787778575; // 有效 6~7位
        //cout<<setprecision(15)<<a;
        
        const int b =1;
        
        //枚举用字母代替数字
        //enum num{zero, one, two, three}; //默认从0开始计算
        enum num{zero=100, one, two=300, three}; //默认从0开始计算
    
        cout<<one;
    
        num n = zeros;
        if(n == zero)
        {
            cout<<"yes";
        }else{
            cout<<"no";
        }
        
    
        return 0;
    }

    类的定义与使用:

    #include <iostream>
    
    using namespace std;
    
    class man{
    public:
        void getHeight(){
            cout<<height;
        }
        void getWeight();
        void setWeight(int);
    public:
        int height=0;
        int weight;
    };
    
    void man::getWeight(){
        cout<<weight;
    }
    
    void man::setWeight(int n){
        weight=n;
    }
    
    int main()
    {
        
        man p ;
        p.setWeight(10);
        p.getWeight();
    
        return 0;
    }

    内联函数:(函数体比较小时比较好)

    #include <iostream>
    
    using namespace std;
    
    //效率更高,不必跳来跳去
    //编译器不会真正的创建该函数,只是将这个函数的代码拷贝到调用的函数中,提高了效率,增大了程序的体积
    inline void print();
    void print()
    {
        cout<<"yes";
    }
    
    class man{
    public:
        void getHeight();
    private:
        int height;
    };
    
    void man::getHeight()
    {
        cout<<height;
    }
    
    int main()
    {
        //print();
        man p;
        p.getHeight();
    
        return 0;
    }

    const函数

    class man{
    public:
        void getHeight();
        void setHeight() const { //不想让某个成员函数修改成员变量的值
            height = 5;
        }
    private:
        int height;
    };

    构造函数

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        int height;
    
    public:
        //注意构造函数没有返回值,不用表明返回值类型
        man(int h){
            height =h;
        }
        void getHeight();
        void setHeight() { //不想让某个成员函数修改成员变量的值
            height = 5;
        }
    };
    
    
    int main()
    {
        man p(55);
        cout<<p.height;
        return 0;
    }

    构造函数与析构函数

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        int height;
    
    public:
        //注意构造函数没有返回值,不用表明返回值类型
        man(int h){
            height =h;
        }
    
        //不能有返回值和参数,有且只有一个
        ~man()
        {
    
        }
    
        void getHeight();
        void setHeight() { //不想让某个成员函数修改成员变量的值
            height = 5;
        }
    };
    
    
    int main()
    {
        man p(55);
        cout<<p.height;
        return 0;
    }

    堆中创建变量和对象

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        void getHeight(){
            cout<<height;
        }
        void setHeight()  { //不想让某个成员函数修改成员变量的值
            height = 5;
        }
    private:
        int height;
    };
    
    
    int main()
    {
        //定义时进行初始化
        //int *p=0;
        int *p=new int;
        *p = 1; //变量保存在堆中
        cout<<*p;
    
        delete p;
        p=0;
    
        man *p1 = new man;
        (*p1).setHeight(); // 或 p1.setHeight();
        (*p1).getHeight();
    
        delete p1;
        p1=0;
    
        return 0;
    }

    //堆栈内存中变量的释放

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        man(){
            cout<<"construct 
    ";
        }
        ~man(){
            cout<<"destruct 
    ";
        }
    };
    
    int main()
    {
        //在栈中分配的系统帮你释放
        man person ;
    
        //在堆中分配的要手动释放
        man *p=new man;
        delete p;
    
        return 0;
    }

    this指针

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        man(int sex){
            //this指针指向当前对象,由编译器来删除
            this->sex=sex; //解决了命名冲突的问题
            cout<<this<<"
    ";
        }
        int sex;
        
    };
    
    int main()
    {
        man p(5);
        cout<<&p<<"
    ";
        cout<<p.sex<<"
    ";
    
        return 0;
    }

     指针的释放

    #include <iostream>
    using namespace std;
    
    int main()
    {
        int *p=new int;
        *p=3;
    
        cout<<p<<"
    ";
        delete p;
        p=0; //一定要 赋值为 0
    
        int *p1=new int;
        cout<<p<<"
    "; //会和p1的地址一样
        cout<<p1<<"
    ";
    
        *p=33;
    
        cout<<*p1<<"
    ";
    
        return 0;
    }

    引用就是别名,是常量,必须进行初始化

    #include <iostream>
    using namespace std;
    
    int main()
    {
        
        int a=1;
        int &b=a; //引用就是别名,地址是相同的,是常量,必须进行初始化
    
        b=2;
    
        cout<<a<<b;
        cout<<&a<<"	"<<&b;
        return 0;
    }

    别名传递

    #include <iostream>
    using namespace std;
    
    void swap1(int &a, int &b)
    {
        int c;
        c=a;
        a=b;
        b=c;
    }
    
    
    int main()
    {
        int a=1,b=2;
        swap(a,b);
        cout<<a<<"	"<<b;
    
        return 0;
    }

    按指(针)传递

    #include <iostream>
    using namespace std;
    
    void swap(int *a, int *b)
    {
        int c;
        c=*a;
        *a=*b;
        *b=c;
    }
    
    
    int main()
    {
        int a=1,b=2;
        swap(&a, &b);
        cout<<a<<"	"<<b;
    
        return 0;
    }

    值传递对象的开销

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        man(){cout<<"construct 
    ";}
        man(man&){cout<<"copy 
    ";}//在栈中创建临时对象的拷贝时调用
        ~man(){cout<<"destruct 
    ";}
    
    };
    
    man test(man one)
    {
        return one;
    }
    
    int main()
    {
    
        man p;
        test(p);
        
        return 0;
    }
    
    /**
    construct
    copy
    copy
    destruct
    destruct
    destruct
    请按任意键继续. . .
    */

     优化1

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        man(){cout<<"construct 
    ";}
        man(man&){cout<<"copy 
    ";}//在栈中创建临时对象的拷贝时调用
        ~man(){cout<<"destruct 
    ";}
    
    };
    
    man test(man *one)
    {
        return *one;//按值返回,会返回对象的副本
    }
    
    int main()
    {
    
        man p;
        test(&p);
        
        return 0;
    }

    优化2(指针方式传递)

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        man(){cout<<"construct 
    ";}
        man(man&){cout<<"copy 
    ";}//在栈中创建临时对象的拷贝时调用
        ~man(){cout<<"destruct 
    ";}
    
    };
    
    man* test(man *one)
    {
        return one;//按值返回,会返回对象的副本
    }
    
    int main()
    {
    
        man p;
        test(&p);
        
        return 0;
    }

    按值传递增加const(增加包含机制)

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        man(){cout<<"construct 
    ";}
        man(man&){cout<<"copy 
    ";}//在栈中创建临时对象的拷贝时调用
        ~man(){cout<<"destruct 
    ";}
        int a;
    };
    
     const man* const test(const man *const one)
    {
        return one;
    }
    
    int main()
    {
    
        man p;
        const man * const p1 = test(&p);
        p1++;
        
        return 0;
    }

    引用于指针

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        man(){cout<<"construct 
    ";}
        man(man&){cout<<"copy 
    ";}//在栈中创建临时对象的拷贝时调用
        ~man(){cout<<"destruct 
    ";}
        int a;
    };
    
     const man& test(const man &one)
    {
        cout<<&one<<"
    ";
        return one;
    }
    
    int main()
    {
        int *p=new int;
        *p=2;
        int *&r=p;//指针的别名
        //int &r=*p;//指针的值别名
    
        cout<<*p<<endl;
        cout<<*r<<endl;
        //cout<<r<<endl;
    
    }
    #include <iostream>
    using namespace std;
    
    
    int main()
    {
        int *&p=new int;
        
        *p=13;
    
    }

    引用与指针,返回时的内存释放情况

    #include <iostream>
    using namespace std;
    
    class a{
    public:
        a(int x){
            this->x=x;
        }
        a(a &b){this->x=b.x;cout<<"copy";}
    
    public:
        int x;
    
    };
    
    a test1()
    {
        //如果引用是一个临时变量副本,那么这个临时变量的生存期会不少于这个引用的生存期。
        a b(10);
        return b;  //返回的并非 b对象,而是其副本
    }
    
    a& test2()
    {
        a b(11); //返回局部变量或临时变量的地址
        return b; 
    }
    
    
    int main()
    {
        a b = test1();  //right
        a *b = &test1();  //如果用指针来接收则不对,副本的内存地址会被立刻释放(但里面的数据可能没有被清楚,所以看起来仍旧是对的)
    
        cout<<b.x<<endl;
    
    }

    返回对象副本导致内存泄露 

    #include <iostream>
    using namespace std;
    
    class a{
    public:
        a(int x){
            this->x=x;
        }
        a(a &b){this->x=b.x;cout<<"copy";}
    
    public:
        int x;
    
    };
    
    a test()
    {
        a *p =new a(10);
        return *p;  //返回的对象的副本(分配到栈上),而 p被释放了,会出现内存泄露
        //要解决内存泄露就不能反悔对象副本,而是返回指针或别名
    }
    
    
    int main()
    {
        a &b = test();
    
        /*
        这种是错误的,只有栈上的空间采用delete释放
        a *p = &b;
        delete p;
        p=0;
        */
    
        cout<<b.x<<endl;
    
    }

    解决上面的问题:

    #include <iostream>
    using namespace std;
    
    class a{
    public:
        a(int x){
            cout<<"constuct"<<endl;
            this->x=x;
        }
        a(a &b){this->x=b.x;cout<<"copy";}
        ~a()
        {
            cout<<"destruct"<<endl;
        }
    
    public:
        int x;
    
    };
    
    a& test()
    {
        a *p =new a(10);
        cout<<p<<endl;
        return *p;
    }
    
    
    int main()
    {
        a &b = test();
        cout<<b.x<<endl;
        cout<<&b<<endl;
    
        a *p = &b;
        delete p;
        p=0;
    
        //注意 此时b别名已经不可以再使用了
    
    }

    函数、方法都支持重载,默认值

    #include <iostream>
    using namespace std;
    
    void test(int a, int b=3)
    {
        cout<<a<<" "<<b<<endl;
    }
    
    void test()
    {
        cout<<"haha"<<endl;
    }
    
    
    int main()
    {
        test();
        test(5);
        test(5,55);
    
        return 0;
    
    }

    成员变量赋初值

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        //man():age(10),sex(1){}
        man(){age=10;sex=1;}
        
        //man(int age=10,int sex=1) {this->age=age; this->sex=sex;}
    
    
    public:
        int age;
        int sex;
    
    };
    
    
    int main()
    {
        man son;
    
    cout<<son.age<<endl;
    
        return 0;
    
    }

    成员变量的初始化

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        man():age(10),sex(1){} //初始化
    
    public:
        const int age; //@notice
        cosnt int sex;
    
    };
    
    
    int main()
    {
        man son;
    
    cout<<son.age<<endl;
    
        return 0;
    
    }
    #include <iostream>
    using namespace std;
    
    class man{
    public:
        explicit man(int x){age=x;cout<<"consctruct"<<endl;} //关闭类型转换的特性
        void setAge(int num){age=num;}
        void getAge(){cout<<age<<endl;;}
        ~man(){cout<<"desctruct"<<endl;}
    
    public:
        int age;
    
    };
    
    
    int main()
    {
        man son(10);
        son.getAge();
    
        son=100; //等价于 son = man(100); 强制类型转换,显式转换
    
        return 0;
    
    }

    复制的对象中成员变量有指针

    成员拷贝,浅拷贝

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        man(){p=new int();*p=110;cout<<"consctruct:"<<age<<endl;}
        man(man &a){
            p=a.p;
            cout<<"copy:"<<age<<endl;
        }
        ~man(){cout<<"desctruct:"<<age<<endl;delete p;p=NULL;}
        void setAge(int num){age=num;}
        int getAge(){return age;}
        int getP(){return *p;}
        void setP(int x){*p = x;}
        
    
    public:
        int age;
        int *p;
    
    };
    
    
    int main()
    {
        man *p1 = new man();
        man b = (*p1); //当复制的对象的成员有指针时,指针指向的相同的内存地址,当一个对象析构时,另一个对象的指针也不可以用了
    
        p1->setAge(55);
    
        b.setP(4);
        b.setAge(44);
    
    delete p1; 
    //main函数执行完毕后,会释放 b,再次执行 析构函数释放p,但此时p已经为空,则程序会崩溃
        cout<<p1->getP()<<endl;
        cout<<p1->getAge()<<endl;
    
        return 0;
    
    }

    深层拷贝

    #include <iostream>
    using namespace std;
    
    class man{
    public:
        man(){p=new int();*p=110;cout<<"consctruct:"<<age<<endl;}
        man(const man &a){ //增加const更好
            p = new int();
            *p = *(a.p);
            cout<<"copy:"<<age<<endl;
        }
        ~man(){cout<<"desctruct:"<<age<<endl;delete p;p=NULL;}
    
        void setAge(int num){age=num;}
    
        int getAge(){return age;}
    
        int getP(){return *p;}
    
        void setP(int x){*p = x;}
        
    
    public:
        int age;
        int *p;
    
    };
    
    
    int main()
    {
        man *p1 = new man();
        man b = (*p1); //当复制的对象的成员有指针时,指针指向的相同的内存地址,当一个对象析构时,另一个对象的指针也不可以用了
    
        p1->setP(22);
        cout<<p1->getP()<<endl; // 22
        cout<<b.getP()<<endl; // 默认值 110
    
        b.setP(44);
        cout<<p1->getP()<<endl;  // 22 
        cout<<b.getP()<<endl; // 44
    
        delete p1; 
    
        cout<<b.getP()<<endl; // 44 删除p1后b不受影响
    
        return 0;
    
    }

    运算符重载

    #include <iostream>
    using namespace std;
    
    class num{
    public:
        num(){x=1;}
        int getX(){
            return x;
        }
        
        void setX(int x)
        {
            this->x = x;
        }
    
        //运算符重载
        void operator++(){
            x++;
        }
    
    private:
        int x;
    };
    
    
    int main()
    {
        num a;
        ++a;  // 等价于  a.operator++();
    
        //num j=++a; 这样是错误的相当于 j=a.operator++(), 而其没有返回值
    
        cout<<a.getX()<<endl;
    
    }

    解决上面的问题(创建临时对象)

    #include <iostream>
    using namespace std;
    
    class num{
    public:
        num(){x=1;}
        int getX(){
            return x;
        }
        
        void setX(int x)
        {
            this->x = x;
        }
    
        //运算符重载
        num operator++(){
            x++;
    
            num tmp ;
            tmp.setX(x);
            return tmp;
        }
    
    private:
        int x;
    };
    
    
    int main()
    {
        num a;
        ++a;  // 等价于  a.operator++();
    
        num j=++a; 
    
        cout<<j.getX()<<endl;
    
    }

    创建对象的3种方式:

    #include <iostream>
    using namespace std;
    class A
    {
    private:
        int n;
    public:
        A(int m):n(m)
        { }
        ~A(){}
    };
    int main()
    {
        A a(1);  //栈中分配 隐式调用
        A b = A(1);  //栈中分配 显式调用
        A* c = new A(1);  //堆中分配
      delete c;
        return 0;
    }

    创建无名临时对象

    #include <iostream>
    using namespace std;
    
    class num{
    public:
        num(){x=1;}
        num(int x){this->x=x;}
        int getX(){
            return x;
        }
        
        void setX(int x)
        {
            this->x = x;
        }
    
        //运算符重载
        num operator++(){
            x++;
    
            return num(x);
        }
    
    private:
        int x;
    };
    
    
    int main()
    {
        num a;
        ++a; 
    
        num j=++a; 
    
        cout<<j.getX()<<endl;
    
    }

    重载赋值运算符

    #include <iostream>
    using namespace std;
    
    class num{
    public:
        num(){x=1;cout<<"construct"<<x<<endl;}
    
        num(int x){this->x=x;cout<<"construct:"<<x<<endl;}
    
        ~num(){cout<<"destruct:"<<x<<endl;}
    
        num(num &a){this->x=a.x;cout<<"copy:"<<x<<endl;}
    
        int getX(){
            return x;
        }
        
        void setX(int x)
        {
            this->x = x;
        }
    
        //运算符重载
         num operator+(num &r){
            
            return num(x+r.getX());
        }
    
        void operator=(num &r){
            cout<<"operator+"<<endl;
            
        }
    
    private:
        int x;
    
    };
    
    
    
    
    int main()
    {
        
        num a(11),b(22);
    
        b = a;
    
        return 0;
    }
  • 相关阅读:
    HDU-4027-Can you answer these queries?
    Python的多协程(三种简单生成多协程方法)
    关于django 如何实现简单api的restful 接口
    flask 框架服务原理
    DVWA渗透测试环境搭建
    装饰器 python 你也可以叫语法糖
    websocket python实现原理
    robotframe 自定义开发库
    mysql linux 安装卸载
    python+jenkins 构建节点环境编译器配置问题
  • 原文地址:https://www.cnblogs.com/siqi/p/4574394.html
Copyright © 2020-2023  润新知