C++语言解读三

今天说说继承.在C++中继承分共有继承,私有继承,多继承和单一继承,这点和C#不同,另外vritual关键字的用法也不相同,下面一一讲解

1:公有单一继承

 

 

#include<iostream>
using namespace std;
//公有单一继承 例子
class A
{
public:
    void print1()const{cout<<"父类方法"<<endl;}
};
class B:public A
{
public:
    void Print2()const{cout<<"子类方法"<<endl;}
};
int main()
{
    B b;//栈中创建对象
    b.print1();//父类方法
    b.Print2();//自己的方法
    return 0;
}
/*
   程序说明
     子类在公有继承父类后,父类的公有方法在子类中依然是公有方法
*/

 

 

2:公有多继承

 

#include<iostream>
using namespace std;
//公有多继承例子
class A
{
public:
    void print1()const{cout<<"A类方法"<<endl;}
};
class B
{
public:
    void Print2()const{cout<<"B类方法"<<endl;}
};
class C:public A,public B
{
public:
    void Print3()const{cout<<"C类方法"<<endl;}
};
int main()
{
    C c;
    c.print1();//A方法
    c.Print2();//B方法
    c.Print3();//C方法
    return 0;
}

 

 

3:多继承(有公有和私有一起)

 

#include<iostream>
using namespace std;
//多继承(有公有和私有一起)
class A
{
public:
    void print1()const{cout<<"A类方法"<<endl;}
};
class B
{
public:
    void Print2()const{cout<<"B类方法"<<endl;}
};
class C:public A,private B
{
public:
    void Print3()const{cout<<"C类方法"<<endl;}
    void Print4(){Print2();}
};
int main()
{
    C c;
    c.print1();//A方法
    
//c.Print2();//这里调用B类方法不能运行
    c.Print3();//C方法
    c.Print4();//这里调用B类方法
    return 0;
}
/*
   程序说明

     1:私有继承用private关键字
     2:私有继承有父类的公有方法在子类里就变成私有方法
     3私有继承有父类的私有方法在子类里就变成不可访问
     如需方法,就在子类里添加公有接口方法(就像程序里的Print4()方法一样来调用)
*/

 

 

4单一继承中的构造函数执行顺序

 

 #include<iostream>
using namespace std;
//单一继承中的构造函数执行顺序
class A
{
public:
    A(){cout<<"父类构造函数执行"<<endl;}
};
class B:public A
{
public:
    B(){cout<<"子类构造函数执行"<<endl;}
};
int main()
{
    B b;
    return 0;
}
/*
    程序说明

     在创建子类后先构造它的父类的构造函数,然后在构造自己
*/

 

 

5多继承中的构造函数执行顺序

 

#include<iostream>
using namespace std;
//多继承中的构造函数执行顺序
class A
{
public:
    A(){cout<<"A类构造函数执行"<<endl;}
};
class B
{
public:
    B(){cout<<"B类构造函数执行"<<endl;}
};
class C
{
public:
    C(){cout<<"C类构造函数执行"<<endl;}
};
class D:public A,public B,public C
{
public:
   D(){cout<<"D类构造函数执行"<<endl;}
};
int main()
{
    D d;
    return 0;
}
/*
    程序说明

     在多继承中构造函数的执行顺序为第一个继承的先构造
     这里将会先构造A,然后B,最后C
*/

 

 

 

6继承中的析购函数执行顺序

 

 

#include<iostream>
using namespace std;
//继承中的析购函数执行顺序
class A
{
public:
    A(){cout<<"A类构造函数执行"<<endl;}
    ~A(){cout<<"A类析购函数执行"<<endl;}
};
class B
{
public:
    B(){cout<<"B类构造函数执行"<<endl;}
    ~B(){cout<<"B类析购函数执行"<<endl;}
};
class C
{
public:
    C(){cout<<"C类构造函数执行"<<endl;}
    ~C(){cout<<"C类析购函数执行"<<endl;}
};
class D:public A,public B,public C
{
public:
   D(){cout<<"D类构造函数执行"<<endl;}
   ~D(){cout<<"D类析购函数执行"<<endl;}
};
int main()
{
    D d;
    return 0;
}
/*
    程序说明

     在多继承中析购函数的执行顺序为先析购子类,然后一级一级的析购下去
*/

 

 

 

7:多继承中出现的两义性,什么是两义性呢?请看代码

 

#include<iostream>
using namespace std;
class A
{
public:
    void Print(){cout<<"类A方法"<<endl;}
};
class B:virtual public A
{
};
class C:virtual public A
{
};
class D:public B,public C
{

};
int main()
{
    D d;
    //d.Print();这里会出现ambiguous错误。
    
//编译器会提示这个Print是从类A继承的还是从类B继承的,它不明白
    
//下面是正确的调用
    d.C::Print();//用类名加双冒号调用
    return 0;
}
/*
    程序说明

     
*/

 

 

 

8:虚基类是不会产生两义性这个问题呢,那么怎么定义虚基类呢?请看代码

 

 

#include<iostream>
using namespace std;
//两义性
class A
{
public:
    void Print(){cout<<"类A方法"<<endl;}
};
class B:virtual public A
{
};
class C:virtual public A
{
};
class D:public B,public C
{

};
int main()
{
    D d;
    d.Print();
    return 0;
}
/*
    程序说明

     用virtual关键字定义虚基类
*/

 

 

9:virtual关键字的使用

 

#include<iostream>
using namespace std;
//虚函数
class A
{
public:
    virtual void Print(){cout<<"类A方法"<<endl;}
};
class B:virtual public A
{
public:
    void Print(){cout<<"类B方法"<<endl;} 
};
int main()
{
    //定义指向类A指针
    
//指针多态
    A* p=new A;
    p->Print();//这里将访问类A方法
    p=new B;
    p->Print();//这里将会访问类B方法
    
//=-==============
    
//可能有些使用C#的程序员觉得这是必然的。
    
//这里如果我们不用指针,而转用对象,看看是什么情况
    A a;
    B b;
    a.Print();
    a=b;//注意这里将类B的一个对象赋予给类A的一个对象,再次调用a.Print()方法看看
    a.Print();//这里还是会访问类A方法
    return 0;
}
/*
    程序说明

      在动态联编情况下。如果程序实现多态必须用指针或引用,用对象是不可以的
*/

 

 

 

最后写一个小的程序来最终说明虚函数的使用

 

#include<iostream>
using namespace std;
class Language
{
public:
    virtual void Print()
        const
    {
       cout<<"程序默认使用语言为Java"<<endl;
    }
};
class Cshop:public Language
{
    void Print()
        const
    {
       cout<<"程序使用C#语言编写"<<endl;
    }
};
class Cpp:public Language
{
    void Print()
        const
    {
       cout<<"程序使用C++语言编写"<<endl;
    }
};
class Dephi:public Language
{
    void Print()
        const
    {
       cout<<"程序使用Dephi语言编写"<<endl;
    }
};
int main()
{
    //定义个基类指针
    Language* p;
    Language* p1;
    int con;
    bool bl=true;//退出循环使用
    while(true)
    {
        cout<<"<1>Cshop <2>Cpp <3>Dephi <0>quit";
        cin>>con;
        switch(con)
        {
        case 1:
            p=new Cshop;
            break;
        case 2:
            p=new Cpp;
            break;
        case 3:
            p=new Dephi;
            break;
        case 0:
            bl=false;
            break;
        default:
            p=new Language;
            break;
        }
        if(!bl){
            //输入0情况下退出循环
            break;
        }
        p1=p;
        p1->Print();
    }
    return 0;
}

 

posted @ 2011-12-19 13:40  依人  阅读(610)  评论(6编辑  收藏  举报