C++基础知识

来源:互联网 发布:java培训班都找到工作 编辑:程序博客网 时间:2024/06/18 11:03

基础知识点

C++学习网站:
English:http://en.cppreference.com/w/
中 文 :http://zh.cppreference.com/w/%E9%A6%96%E9%A1%B5
http://www.runoob.com/cplusplus/cpp-tutorial.html

1.类的声明

类名 对象名
例如:
Clock myclock;
注意:对象占据的内存只存放数据成员,每个函数在内存中只占据一份空间。

2. 模板类

a.模板的声明

template<class T>    class A{       public: T a;        T b;        T hy(T c, T &d);       void h();};

b.类模板外部定义成员函数的方法

template<模板形参列表>   函数返回类型 类名<模板形参名>::函数名(参数列表){函数体},  

比如有两个模板形参T1,T2的类A中含有一个voidh()函数,则定义该函数的语法为:

template<class T1,class T2>void A<T1,T2>::h(){}

c.类模板对象的创建

比如一个模板类A,则使用类模板创建对象的方法为A< int > m;

3.继承

派生类不继承基类的构造函数与析构函数。

(1). 公有继承

基类的public和protected 的访问属性在派生类中不变,而基类的private不可访问

(2). 私有继承

基类的public和protected的访问属性在派生类中变成private属性,而基类的private不可访问

(3). 保护继承

基类的public和protected的访问属性在派生类中变成rotected属性,而基类的private不可访问(protected可以被派生类访问,但不能被对象访问)

(4). 类型兼容

通过以下方式调用基类函数(适用于继承多个基类,与多态正相反):
基类 p=派生类
p.fun();
或 基类 *p=派生类
p->fun();

class base1{    public:    void display()const{cout<<"base1::diaplay"<<endl;}};class base2:public base1{    public:    void display()const{cout<<"base2::diaplay"<<endl;}};class derived:public base2{    public:    void display()const{cout<<"base3::diaplay"<<endl;}};void fun(base1 * base){    base->display();};int main (){   base1 fun1;   base2 fun2;   derived fun3;   fun(&fun1);   //输出base1::diaplay   fun(&fun2);   //输出base1::diaplay   fun(&fun3);   //输出base1::diaplay   return 0;

(5). 派生类的构造函数

派生类构造函数执行顺序:
1. 调用基类构造函数,调用顺序按照他们被继承时申明的顺序(从左向右),调用的方式按照派生类构造函数初始化列表确定(列表无基类构造函数声明则调用基类默认构造函数,有的话根据参数调用对应的构造函数)
2. 对派生类新增的成员对象初始化,调用顺序按照它们在类中的声明顺序
3. 执行派生类的构造函数体中的内容

a. 基类最好写默认构造函数,不然派生类调用默认构造函数的时候回找不到基类的构造函数导致编译失败。
b. 如果继承方式是 A -> B -> C

则派生构造的调用方式是 A -> B -> C

class base1{    public:    base1(){cout<<"base1::inital"<<endl;}    base1(int i){cout<<"base1::diaplay"<<i<<endl;}    base1(char i){cout<<"base1::char"<<i<<endl;}};class base2{    public:    base2(){cout<<"base2::diaplay"<<endl;}};class base3{    public:    base3(int m){cout<<"base3::diaplay"<<m<<endl;}    base3(){cout<<"base3::inital"<<endl;}};//类的声明确定基类构造函数的执行顺序class derived:public base3,public base1,public base2{    public://派生类构造函数的基类声明确定上面的调用基类构造函数的类别,无声明则调用默认    derived(char i,int j,int n,int k):base1(i),menber3(k),menber1(n),base3(j){};    base1 menber1;  //派生类成员依次初始化    base2 menber2;    base3 menber3;};int main (){   derived  obj(1,2,3,4);   return 0;}//输出结果:base3::display2base1::char?base2::displaybase1::display3base2::displaybase3::display4

(6) 派生类的析构函数

调用方式与构造函数正好相反:
派生类析构函数体-> 派生类对象成员所在类的析构函数 -> 基类析构函数

(7)派生作用域

(1) 如果派生类含有与基类相同的变量和函数,则会隐藏基类的变量与函数,如果需要调用基类的成员则需加作用域,如下:

graph TDbase0-->base1base0-->base2base1-->derivedbase2-->derived
derived.base1::val=2;derived.base1::fun();

(2)如果base0含有独一无二的成员。

调用方法1:添加作用域

derived.base1::val=2;derived.base1::fun();

调用方法2:使用虚基类

class base1:virtual public base0{    xxx}class base2:virtual public base0{    xxx}derived.val=2;derived.fun();

(8)组合与继承

  • 组合是“有一个”(has-a)的关系
    解释:整体与一部分的关系,好比汽车与零件
  • 继承是“是一个”(is-a)的关系
    解释:特殊与一般的关系,好比汽车、卡车等与车的关系

4. 多态性

1. 多态的类型

  • 重载多态
  • 强制多态
  • 包含多态
  • 参数多态

2. 多态的实现

  • 编译时的多态
  • 运行时的多态

3. 不能重载的运算符

  • 类属关系运算符“.”
  • 成员指针运算符“.*”
  • 作用域分辨符“::”
  • 三目运算符“?:”

4. 使用方式 (一个基类,多个派生类,与继承相反)

多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定。
  那么多态的作用是什么呢,封装可以使得代码模块化,继承可以扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用。也就是说,不论传递过来的究竟是那个类的对象,函数都能够通过同一个接口调用到适应各自对象的实现方法。

基类 virtual void display();
派生类1 void display();
派生类2 void display();

base *p=派生类xp->display();//显示方式根据派生类x而定

5. 纯虚函

实例:virtual void display() = 0;

原创粉丝点击