▲函数的重载条件:函数名相同,参数类型和(或)参数个数不同.
下面两种情况不能构成函数重载:
1.只有返回类型不同
int fun();
void fun();
2.参数混淆
int fun(int a,int b=2);
int fun(char a);
▲变量的引用
引用可看作是变量的别名,且必须在定义时初始化.
int a;
int &b=a; //变量b引用了a,b和a的内存地址相同
b=5; //a和b都是5
▲指向常量的指针和指针常量
指向常量的指针可以更改指向的地址,不能改变指向地址所表示的内容。
const int *a; //定义指向常量的指针,也可写成int const *a
int b,c;
b=1;
c=2;
a=&b;
*a=3; //错误,不能改变指向地址所表示的内容
a=&c; //正确,可以更改指向的地址
指针常量能够更改指向地址所表示的内容,不能改变指向的地址,且必须在定义的时候初始化。
int * const d=&b; //定义指针常量
d=&c; //错误,不能改变指向的地址
*d=3; //正确,可以更改指向地址所表示的内容
▲权限关键字 public,private,protected
public:无限制
protected:对象内部和继承对象内部可见
private:仅对象内部可见
▲struct内成员缺省为public,class内成员缺省为private,除此之外在c++中struct和class是通用的.
▲构造函数没有返回值,函数名与类名相同,可重载构造函数,实例化对象时由系统自动调用不带参数的构造函数.
当希望系统调用带有参数的构造函数时
class cls
{
cls(int a,int b) //构造函数带有参数
{
...
}
} ;
cls mycls(1,2); //1,2传递给构造函数
▲析构函数 没有参数和返回值,函数名为~类名,对象消亡时由系统自动调用析构函数,每个类只能有一个析构函数.
▲this指针:类所实例化的每一个对象都隐含有一个this指针,this指针指向对象自身,由系统指定.例如在对象中a=1等同于this->a=1
this指针的一个用法是,当成员函数的参数名与成员数据名相同时,通过this->指定成员数据,避免混淆.
class cls
{
public:
int a,b;
cls(int a,int b) // 参数名与成员数据名相同
{
this->a=a;
this->b=b;
}
} ;
▲类的继承 子类:继承方法 父类
class a
{
...
};
class b : public a //子类b继承父类a
{
...
};
▲继承方法
public :父类中public,protected,private被子类继承为public,protected,NULL
protected:父类中public,protected,private被子类继承为protected,protected,NULL
private:父类中public,protected,private被子类继承为private,private,NULL
▲子类的构造与析构
子类实例化对象时,首先执行父类构造函数,再执行子类构造函数.
给父类构造函数传递参数的方法如下:
class a
{
public:
a(int x,int y) //系统默认调用不带参数的构造函数,子类应传递参数告诉系统执行带参构造函数
{
...
}
} ;
class b : public a
{
public:
b():a(1,3) //向父类构造函数传递参数
{
...
}
};
子类实例化对象消亡时,首先执行子类的析构函数,再执行父类的析构函数.
▲类中常量的初始化
构造函数:常量名(初始值)
class a
{
public:
const int b;
cls():b(22) //常量b被22初始化,多个常量可用,分隔
{
...
}
} ;
▲作用域标识符::
子类中出现与父类中名字相同的变量或函数时, 子类的变量或函数会将父类中的同名变量或函数覆盖.
若要在子类中访问父类中的同名变量或函数应使用作用域标识符::
class a
{
public:
int x;
void fun()
{
....
}
};
class b : public a
{
public:
int x;
void fun()
{
....
}
void test()
{
cout<<x<<endl; //子类的x
cout<<a::x<<endl; //父类的x
fun(); //子类的fun函数
a::fun(); //父类的fun函数
}
};
▲虚函数
class c
{
public:
void fun()
{
cout<<"this is c"<<endl;
}
};
class d:public c
{
public:
void fun()
{
cout<<"this is d"<<endl;
}
};
main()
{
c* cc;
d dd;
cc=ⅆ //将子类对象的地址传递给指向父类对象的指针
cc->fun(); //输出为
this is c
}
希望的结果是this is d,为此需要使用虚函数,将class c改成如下:
class c
{
public:
virtual void fun() //虚函数
{
cout<<"this is c"<<endl;
}
};
此时main运行结果为this is d.且子类中的fun()不管有无virtual关键字也成为虚函数.
必须先使用基类指针指向子类的对象,然后使用基类指针调用虚函数,根据不同的类对象,调用其相应的函数,若子类中没有该函数则调用父类的.虚函数只能出现在类中.
▲纯虚函数
没有函数体的虚函数,形如virtual void fun()=0;
含有纯虚函数的类叫抽象类且不能实例化对象只能作为父类,可在子类中具体实现该函数体,用子类实例化对象.
class a
{
public:
virtual int fun(int x)=0; //纯虚函数
};
class b:public a
{
public:
void int fun(int x) //实现纯虚函数体
{
cout<<x<<endl;
return x;
}
};
main()
{
a aa; //错误,a不能实例化对象
b bb;
}
▲在类的定义外定义成员函数
返回类型 类名::函数名(参数)
{
....
}
如下:
class a
{
public:
int fun(int x); //仅声明
};
int a::fun(int x) //对类a中函数的定义
{
...
}
▲静态成员变量
静态成员变量的所有者是类本身和类实例化的对象,可用于多对象共享数据。静态成员变量不能在类定义里或构造函数中或头文件中初始化,只能在类定义外的源文件中初始化。
class a
{
public:
static int x;
...
};
int a::x=1; //类定义外初始化静态成员变量
▲静态成员函数
静态成员函数不属于对象,只属于类本身, 因此他没有this指针,同时不依赖类所实例化的对象就可直接使用的类中成员函数
static 返回类型 函数名(变量名)
静态函数的声明和定义必须在类的定义中,且静态函数不能访问类中非静态的成员变量
class a
{
public:
static int x;
int y;
static int fun(int x)
{
cout<<x; //正确
cout<<y; // 错误,不能访问非静态的成员变量
}
};
int a::x=1;
main()
{
a::fun(); // 不依赖类所实例化的对象, 直接使用的类中成员函数
}