一、字节对齐准则:
1.编译器先找到结构体成员中最大字节数成员,然后开始分配第一个这样大的空间,依次来容纳数据成员;不足补0。
struct struct1
{
int i;
char ch;
double d;
short s;
float f;
long l;
};
先分配最大字节数8,int 4可容下,char 1可容下 ,double不能容下,再分配8个字节,依次类推。可得:(4+1+3)+8+(2+4+2)+(4+4)=32
VC下,char->unsigned char ->1;short int ->2;int -> unsigned int ->4;double ->long double->8(默认有符号)
二、静态成员与const成员函数
1、声明与初始化
class A
{
public:
static int y;
public:
A();
static int getvalue();
};
int A::y=10;//类外初始化,无static
A a;
Int A::getvalue()//无static,区别全局静态函数
静态变量公有的访问方式:A::y或者 a.y
静态变量私有保护的访问方式:静态成员函数
初始化列表不可初始化静态变量
静态成员函数,类中不可以重名,不能是虚函数,不能是const、volatile,不能访问静态成员以外的数据
2、类组合初始化
class B
{
public:
B();
private:
A a;
C c;
};
B::B()
{
cout<<"it's B"<<endl;
}
B b;
先构造a ,再构造c,最后构造 b,析构与构造顺序相反
类里面声明的对象,不论什么访问控制,先于本类对象初始化,且按声明顺序初始化,只是声明指针,则不会初始化
3、const
声明:int f() const{},类外定义:int A::f() const{}.此时this指针为const类型,调用对象的值和成员数据的值不能修改,但静态成员变量可以修改,mutable int a,则该成员也可以修改。
This指针默认为* const this
Const int f()返回值为const int类型
Const static 变量可直接在类中初始化;类外用const int A::a=2;//无static
Const 对象不能调用除const函数之外的成员函数
4、类指针
类数据成员指针:int A::*p;
类函数成员指针:int (A::*p)();
5、类继承初始化
与初始化顺序无关:基类构造函数——>类对象构造函数——>自身构造
三、几种特殊函数
1、内联函数inline
不能有循环体和开关函数
类中定义的函数,编译器设置为内联函数
效率高为其特点。
2、友元函数friend
不属于任何类,声明不用类名限制,可访问私有成员,无this指针
公有,私有访问控制没有区别
友元函数的参数一般为对象,才有意义,以获得该对象的数据
几种声明形式:
1. 全局函数
Class B;
Class A
{
friend int getxvalue(B &);
}
int getxvalue(B &b);
2. 类成员函数
Class B;
Class A
{
int getxvalue(B &);
}
int getxvalue(B &b);
class B
{
Friend int A::getxvalue(B &);
}
3.友元类
Class B;
Class A
{
}
class B
{
Friend class A;
}
则 A中成员函数可访问B中的变量
三个特点:不传递、单向性、不继承
3. 拷贝构造函数
Class Rect
{
Int width;
Int height;
}
Rect rect1;
Rect rect2(rect1);此外,函数形参和函数返回值为对象时,会调用拷贝函数
默认拷贝构造函数:
Rect::Rect(const Rect &r)
{
Width=r.width;
Height=r.height;
//重写的时候需要加入些代码
}
即用对象成员数据赋值
构造函数
Rect()
{
P=new int (100);
}
~Rect()
{
If(p!=NULL)
{
Delete p;
}
}
重写拷贝构造函数时,加入
{
P=new int;
*p=*(r.p);
}
同理,赋值的时候,也会调用=可重载的缺省的函数。
4、虚函数(有子类,调用子类,无子类,调用基类)
前加virtual
虚函数必须是非静态成员函数
派生类不必显式加virtual
内联函数、构造函数及静态成员函数不能是虚函数
析构函数可为虚函数,可将基类析构函数定为虚函数
最远派生类声明对象会调用基类的构造函数,其他不会
5、纯虚函数
Virtual 函数类型 函数名称(参数表)=0;
该函数无实际实现,该类为抽象类,未给出该虚函数定义,不能定义该类对象
四、类嵌套
1、声明
Class A{public:class B{};};
Class A::B{};
2、定义
外围类和嵌套类相互独立
嵌套类中,不能在外围类定义函数实现,应该void A::B::b(){};
嵌套类可以访问外围类静态成员,类型名,枚举成员,可不加作用域解析符
外围类A可访问B的公有数据成员,但不适合公有成员函数,m,A a;a.B::b
A a会先调用B的构造函数,然后是A.反过来,只调用B的构造函数
五、类继承
1、公有基类class B: public A
基类public、protected成员等效于继承类的public成员
2、私有基类 class B:private A
基类public、protected成员等效于继承类的private成员
3、保护基类class B:protected A
基类的public、protected成员等价于派生类的protected成员
六、重载与模板(多态性)
1、重载
不可重载的符号:类属关系运算符“.”、成员指针运算符“. *”、作用域说明符“::”、sizeof运算符和三目运算符“? :”。
不会改变运算符的优先级等性质。
声明:
Friend A operator –(const A &a,const A &b)
(单目运算符无参数,双目运算符只有右侧参数)
赋值函数 A& operator =(const A &a) ,为引用返回
2、模板
1> 定义:
Template <class T>
T max(T a,T b){};//参数中必须有模版类型
简单程序实例:
#include "iostream.h"
template <class T>//只是定义这样的一个类型
T add(T a,T b)
{
return a+b;
}
int main(int argc, char* argv[])
{
float x1=10.3;
float y1=9.8;
int x2=2;
int y2=8;
cout<<add(x1,y1)<<endl<<add(x2,y2)<<endl;
return 0;
}
2>类模板
Template <class T>
Class A
{}
或者
Template<class T,T t>//第二参数是一个数,必须为常量
Class A{ private: T t_;}
A<int ,10> temp;合法
或者
Template<class T,class C =char>
有默认值后面的参数都必须有默认值
函数定义:
(每个函数前加)template <class T>
T TestClass<T>::GetData(形参){};
实例化:
A<double> a;
类也可有模板成员
3>模板函数和非模板函数同名调用顺序
先调用与非模板函数的参数一致的函数;参数类型不一致,先转成和非模板函数的参数一致的类型,再调用之。
参考资料:
http://wenku.baidu.com/view/ac80acd384254b35eefd3494.html
http://wenku.baidu.com/view/dddb88b269dc5022aaea0026.html