构造函数异常处理
http://www.mangbar.com/document/8a80809d19fb0c61011a056dbbb71b73
临时变量的产生与常引用
void bar( const string& s){};
void foo( string a){}
void err( string& s){};
//下述两种情况会发生隐式转换
bar(“abc”);//以abc为参数构造一个临时的string
foo(“abc”);//以abc为参数构造一个临时的string
err(“abc”);编译不过 因为对临时对象的修改是无意义的。
Char 的取值范围
-128~127 -128占用的是-0的位置
补码: 最高位为符号为 正数为0,负数为1
正数的补码和原码相同
负数的补码是最高位不变,后面位都取反,最后再加1
堆栈的增长方向
在X86系统中,栈由上往下, 由高地址(0XFFFF)往低地下(0X00000)方向增长
0XFFFF
栈底
|
|
|
栈顶
0X0000
构造与析构异常
高地址 低地址 高字节 低字节
指向变量的指针 总是指向变量的低地址 char *p =(char *) &val; printf("%d",*p); //78 Little Endian
大尾(Big endian)与小尾(little endian) 区别
X86系统采用的是little endian,网络上传输采用的是大尾
little endian 采用高高低低原则上即低字节在低地址 即最开始读的字节是字节流中的低字节.big endian与之相反
以上两个变量在little endian时的布局
0X0001 A 78
0X0002 B 56
0X0003 C 34
0X0004 ‘\0’ 12
Big endian的布局
0X0001 ‘\0’ 12
0X0002 C 34
0X0003 B 56
0X0004 A 78
bool IsLittleEdian()
{
union un
{
char c;
unsigned short int i;
}
un data;
data.i=1;
return 1==data.c;
//char 在union中一直处于低字节,在小尾中它处于低地址 ,在大尾中处于高地址。
}
函数指针"非静态成员函数的函数指针"非静态成员变量的指针:
注意红色的小括号 是必须的 否则会编译出错.
class TM
{
public:
TM(int val = 0):data(val){}
bool SetData(int val)
{data = val; cout<<"data value is set as"<<data<<endl; return true;}
int data;
};
typedef bool (TM::*ClassFunPointer)(int);
typedef int TM::*DataMemberPointer;
ClassFunPointer clsFunPointer = &TM::SetData;
DataMemberPointer dmPointer = &TM::data;
TM tm;
(tm.*clsFunPointer)(10);
tm.*dmPointer =1;
动态对象数组与指针数组:
class Test
{
public:
Test(){cout<<"Test"<<endl;}
Test(int a){cout<<"Test "<<a<<endl;}
~Test(){cout<<"des constructor"<<endl;}
};
不要用基类指针指向一个子类的数组,因为在删除该数组时除非做显示转换 否则会出错。
Base *pB =new Derived[2];
//Wrong way of deletion
delete[]pB//Cause core dump
//Correct way
for(int i=0;i<2;i++)
{
Derived *pD = &(static_cast<Derived *>(pB))[i]);
delete pD;
}
//Consider how about Derived *pD = static_cast<Derived *>(pB);delete [] pD;
构造不定长多维数组
构造动态指针数组/不定长的多维对象数组
变量初始化:
class MB
{
public:
void Foo(){ delete this;}
}
int main()
{
MB *p = new MB;
p->Foo();
delete p; //Cause crash! Because memory pointed by this is already freed.
}
unsigned int 在类型转化时候优先级比int高
unsigned int a = 6;
int b = -20;
(a+b>6)?puts(">6"):puts("<6");
a+b 时转化为unsigned int,所以数值非常大,输出>6.
printf("%d",a+b);//输出-14,因为“%d”,把unsigned int 的(a+b)又转化为 int。
printf("%u",a+b); 才正确
++优先级比*高
char a[] = "Hello!";
char *p =a;
char c = *p++;
cout<<c; //结果是 H
cout<<p; //结果是 ello
虚函数
代码
class A
{
public:
virtual void f1(){cout<<"f1"<<endl;}
virtual void f2(){cout<<"f2"<<endl;}
virtual void f3(){cout<<"f3"<<endl;}
};
class B:public A
{
public:
virtual void f2(){cout<<"B:f2"<<endl;}
};
class C: public B
{
public:
virtual void f3(){cout<<"C:f3"<<endl;}
};
int main()
{
C c;
A *p = &c;
p->f1(); //f1
p->f2(); //B:f2
p->f3(); //C:f3
}
derA.fun();//OK
如果重新定义了基类中的的一个重载成员工函数,则在派生类中其他的重载函数将会被隐藏
代码
class MBase
{
public:
virtual void fun(){};
virtual void fun(int a){};
};
class DeriveA : public MBase
{
public:
//重写基中的一个重载函数
virtual void fun(){};
};
class DeriveB : public MBase
{
public:
//新加一个函数
virtual void fun(char *c){};
};
int main()
{
DeriveA derA;
derA.fun();//OK
//derA.fun(1);//Error! 基类中的fun(int)在子类中被隐藏,因为子类重新定义了基类中的fun(), 它在基类中是重载函数
DeriveB derB;
//derB.fun();//Error 子类中新定义的fun(char c) 隐藏了fun()和fun(int a)
//derB.fun(1);//Error 原因同上
derB.fun("abc");//OK
MBase *base = &derB;
base->fun();//OK
base->fun(1);//OK
return 0;
}
构造函数不能为虚 但类中有至少一个虚函数,析构函数必须是虚的。
虚机制在构造函数中不工作,构造函数中调用的函数都是静态连编的。即使构造函数中有虚函数,也把它视为非虚函数。
虚机制在析构函数中也不工作,析构函数中调用的函数都是静态连编的。即使析构函数中有虚函数,也把它视为非虚函数。




浙公网安备 33010602011771号