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