参数传递 强制类型转换 自动类型转换 临时变量

摘要:
0  关于参数传递类A,有一个int的数据成员0.1  test1,若A中有一个operatorint()的强制类型转换,可以直接传对象。如果传入的实参和形参类型不一致时,如果编译器能找到以上两种转换,则自动转换,否则会报类型不一致错误。1  自动类型转换自动转换发生在不同数据类型的变量混合运算时,由编译系统自动完成。

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  重载强制类型转换运算符

classComplex
{
private:
    inta;
    intb;
public:
    Complex(int i=0, int j=0)
    {
        a=i;
        b=j;
    }
    voidprint()
    {
        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;
        returntmp;
    }
    operator int ()    //重载强制转换类型转换
{
        cout<<"重载强制类型转换运算符\n";
        returna;
    }
};
intmain()
{
    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:拷贝构造函数的三种用法:初始化、传参、函数返回值。

classE
{
public:
    E()
    {
        cout<<"E()"<<endl;
        a = 1;
    }
    E(inti)
    {
        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:
    inta;
};
E fun(E e)
{
    cout<<"fun(E e)"<<endl;
    returne;
}
intmain()
{
/*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 *

classBase
{
public:
    Base(){b = 10;}
    intb;
    void printb(){cout<<"b:"<<b<<endl;}
};
class Derive:publicBase
{
public:
    Derive(){d = 20;}
    intd;
    void printd(){printb();cout<<"d:"<<d<<endl;}
};

intmain()
{
    Base *pb1, *pb2;
    Derive *pd1, *pd2;
    pb1 = newBase();
    pd1 = newDerive();

    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
*/}

免责声明:文章转载自《参数传递 强制类型转换 自动类型转换 临时变量》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇AVR单片机教程——走向高层深度前馈网络下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

基于第三方开源库的OPC服务器开发指南(3)——OPC客户端

本篇将讲解如何编写一个OPC客户端程序测试我们在前文《基于第三方开源库的OPC服务器开发指南(2)——LightOPC的编译及部署》一篇建立的服务器。本指南的目的是熟悉OPC服务器的开发流程,所以客户端部分我就不做过多描述,只是简单讲解几个关键技术细节及其实现函数,完整工程源码请从如下地址获取: https://github.com/Neo-T/OPCDA...

[VC++]一些常用数据类型的使用

我们先定义一些常见类型变量借以说明 int i = 100; long l = 2001; float f=300.2; double d=12345.119; char username[]="bone"; char temp[200]; char *buf; CString str; _variant_t v1; _bstr_t v2; 一、其它数据类...

C指针——C语言手记

近期敲代码的时候。发现自己非常多东西都開始忘了。 今天最终有机会好好总结一下指针。当做个笔记同一时候也希望对大家实用。假设有不对的地方。希望大家能帮我指正一下。然后我的实验环境是32位RHEL+eclipse。 一、指针基本属性 指针的属性主要包含指针的类型、指针所指向的类型、指针的值。以下以一个简单的样例为例 int *p; 指针的类型:int *...

C++中清空缓冲区

C++中标准输入cin有多种输入方式。。 这篇文章罗列的还是简要易懂的。C++输入cin详解。。。如果只是简单的使用cin>>的话,会单个token的读入。但是会忽略换行符,空格,制表符等空白符。其中cin.getline()和cin.get()都会遇到一个非常棘手的事情,就是当输入的字符串,或者说缓冲区中的字符多于第二个参数int的要求时。缓...

聚合类型与POD类型

Lippman在《深度探索C++对象模型》的前言中写道: I have heard a number of people over the years voice opinions similar to those of your colleagues. In every case, those opinions could be attributed...

IOS(数据库的应用)

在iPhone的开发过程中常常会用到数据库,而SQLite3是iPhone中支持的数据库。下面简单介绍一下iPhone中SQLite3数据库的用法: SQLite3简介 SQLite3是一个轻量级的数据库,完全使用C语言编写,使用简单方便。它是一个嵌入到程序进程的数据库,和其他一些数据库(MySQL,MS SQL)不同,它没有独立的进程。 1、打开数据库...