zoukankan      html  css  js  c++  java
  • 参数传递 强制类型转换 自动类型转换 临时变量

    0  关于参数传递

    类A, 有一个int的数据成员
    0.1  test1(int i),若A中有一个operator int()的强制类型转换,可以直接传对象。
      A a;
      test1(a);
    0.2  test2(A b),若A中有一个A(int i)的构造函数,可以直接将int作为参数
      int i = 10;
      test2(i);//这里自动调用A的构造函数,若传的是A的对象,则调用A的拷贝构造函数。如果传入的实参和形参类型不一致时,如果编译器能找到以上两种转换,则自动转换,否则会报类型不一致错误。

    1  自动类型转换
    自动转换发生在不同数据类型的变量混合运算时,由编译系统自动完成。

    2  强制类型转换
    2.1  const char *可以被强制转换成char *从而改变字符串的内容
    2.2  重载强制类型转换运算符

    class Complex
    {
    private:
        int a;
        int b;
    public:
        Complex(int i=0, int j=0)
        {
            a=i;
            b=j;
        }
        void print()
        {
            cout<<"the value is: "<<a<<"+"<<b<<"j\n";
        }
        Complex operator +(const Complex &m)
        {
            Complex tmp;
            tmp.a = a+m.a;
            tmp.b = b+m.b;
            return tmp;
        }
        operator int ()    //重载强制转换类型转换
        {
            cout<<"重载强制类型转换运算符\n";
            return a;
        }
    };
    int main()
    {
        Complex com1(2,2),com2(3,3);
        Complex com3;
        com3 = com1+com2;
        com3.print();    //5+5j
        int t = (int)com3;
        cout<<t<<endl; //5
        int s = 8;
        cout<<s+com1<<endl;//10,系统自动将com1强制类型转换为int
        return 0;
    }

    3 临时变量
    3.1  构造函数的显式调用和隐式调用...不知道术语是什么
    以下来自:www.wutianqi.com/?p=2730
    你可以试试以下代码, 会发现问题。
    class A{
    public:
    A(){};
    A(int t)
    {
    cout<<"Constucting…."<<endl;
    a=t;
    cout<<"a="<<a<<endl;
    }
    private:
    int a;
    };
    int main()
    {
    cout<<"a=12:"<<endl;
    A a;
    a=12;
    cout<<"A b(13)"<<endl;
    A b(13);
    cin.get ();
    }
    a=13,的整个过程其实是,A(int t)先使用13建立一个对象,然后将这个对象赋值给a,这就是所谓隐式转换。
    当你使用explicit修饰的时候,也就把隐式转换关闭了,也就是说你告诉编译器,只有我显示指出调用该构造函数才调用。所以,在有explicit的时候a=13就不能通过了,因为编译器不会自动调用构造函数来帮你完成隐式转换。
    类似:
    CString str("abc");
    char *pstr = "bean";
    str = pstr;//这个过程是先隐式调用CString的构造函数创建一个CString对象,再通过赋值函数将其赋值给str
    PS:拷贝构造函数的三种用法:初始化、传参、函数返回值。

    class E
    {
    public:
        E()
        {
            cout<<"E()"<<endl;
            a = 1;
        }
        E(int i)
        {
            cout<<"E(int i)"<<endl;
            a = i;
        }
        E(const E &e)
        {
            cout<<"拷贝函数"<<endl;
            a = e.a;
        }
        operator = (const E &e)
        {
            cout<<"赋值函数"<<endl;
            a = e.a;
        }
    private:
        int a;
    };
    E fun(E e)
    {
        cout<<"fun(E e)"<<endl;
        return e;
    }
    int main()
    {
    /*    E x;
        int j = 10;
        x = j;//输出为:E()---E(int i)---赋值函数
    */
        E e1, e2;
        fun(2);//输出为:E(int i)---fun(E e)---拷贝函数
        cout<<endl;
        fun(e1);//输出为:拷贝函数---fun(E e)---拷贝函数
        cout<<endl;
        e2 = fun(3);//输出为:E(int i)---fun(E e)---拷贝函数---赋值函数
        cout<<endl;
        e2 = fun(e1);//输出为:拷贝函数---fun(E e)---拷贝函数---赋值函数
        cout<<endl;
    }

    3.2
    CString类向const char *转换
    char a[100];
    CString str("aaaaaa");
    strncpy(a,(LPCTSTR)str,sizeof(a));或strncpy(a,str,sizeof(a));   
    以上两种用法都是正确地. 因为strncpy的第二个参数类型为const char *.所以编译器会自动将CString类转换成const char *
    PS:
    为什么char *p2 = (LPCSTR)str;可以,而char *p2 = (LPSTR)str;不可以
    ansi情况下,LPCTSTR 就是 const char*(LPCSTR)
    3.3  临时变量在哪些情况下用到?(传值 返回值...)
    CString CTestDlgDlg::TestString(LPCTSTR str1, CString str2, char * str3)
    {
        MessageBox(str1);
        MessageBox(str2);
        return "abc";
    }
    3.4 派生类指针向基类指针转换由编译器自动完成,反之,需要强制类型转换,包括传参和赋值
    CtestcefDlg *dDlg = AfxGetMainWnd();//错误,不能从CWnd *转换成CDlg *

    class Base
    {
    public:
        Base(){b = 10;}
        int b;
        void printb(){cout<<"b:"<<b<<endl;}
    };
    class Derive:public Base
    {
    public:
        Derive(){d = 20;}
        int d;
        void printd(){printb();cout<<"d:"<<d<<endl;}
    };
    
    int main()
    {
        Base *pb1, *pb2;
        Derive *pd1, *pd2;
        pb1 = new Base();
        pd1 = new Derive();
    
        pb2 = pd1;//派生类指针向基类指针转换由编译器自动完成
        pd2 = (Derive *)pb1;//反之,需要强制类型转换
    /*
        pd2->printb();//OK
        pd2->printd();//ERROR: 输出的d没有赋值
    */
    /*
        pb2->printb();//OK
        pb2->printd();//ERROR: 'printd' : is not a member of 'Base'
        ((Derive *)pb2)->printd();//OK
    */
    }
  • 相关阅读:
    第一节:SpringMVC概述
    SpringMVC【目录】
    Windows 系统快速查看文件MD5
    (error) ERR wrong number of arguments for 'hmset' command
    hive使用遇到的问题 cannot recognize input
    Overleaf支持的部分中文字体预览
    Understanding and Improving Fast Adversarial Training
    Django2实战示例 第十三章 上线
    Django2实战示例 第十二章 创建API
    Django2实战示例 第十一章 渲染和缓存课程内容
  • 原文地址:https://www.cnblogs.com/apigiraffe/p/2741456.html
Copyright © 2011-2022 走看看