[C++][基础概念](五)继承的学习

对C++中的继承概念一直比较陌生,下面通过几道题来学习它。

     1.下面描述中,表达错误的是(BCD

A.公有继承时基类中的public成员在源生类中仍是public的 正确

B.公有继承时基类中的private成员在源生类中仍是public的 错误,不可见

C.私有继承时基类中的protected成员在源生类中仍是public的 错误,private

D.私有继承时基类中的public成员在源生类中仍是public的 错误,private

解释:

public

protected

private

公有继承

public

protected

不可见

私有继承

private

private

不可见

保护继承

protected

protected

不可见

通过下面的程序来学习:

#include<iostream>
using namespace std;
//
class A       //父类
{
private:
    int privatedateA;
protected:
    int protecteddateA;
public:
    int publicdateA;
};
//
class B :public A      //基类A的派生类B( 有继承)
{
public:
    void funct()
    {
        int b;
        b=privatedateA;   //error:基类中私有成员在派生类中是不可见的
        b=protecteddateA; //ok:基类的保护成员在派生类中为保护成员
        b=publicdateA;    //ok:基类的公共成员在派生类中为公共成员
    }
};
//
class C :private A  //基类A的派生类C(私有继承)
{
public:
    void funct()
    {
        int c;
        c=privatedateA;    //error:基类中私有成员在派生类中是不可见的
        c=protecteddateA;  //ok:基类的保护成员在派生类中为私有成员
        c=publicdateA;     //ok:基类的公共成员在派生类中为私有成员
    }
};
//
class D :protected A   //基类A的派生类D(保护继承)
{
public:
    void funct()
    {
        int d;
        d=privatedateA;   //error:基类中私有成员在派生类中是不可见的
        d=protecteddateA; //ok:基类的保护成员在派生类中为保护成员
        d=publicdateA;    //ok:基类的公共成员在派生类中为保护成员
    }
};
//
int main()
{
    int a; 
 
    B objB;
    a=objB.privatedateA;   //error:基类中私有成员在派生类中是不可见的,对对象不可见
    a=objB.protecteddateA; //error:基类的保护成员在派生类中为保护成员,对对象不可见
    a=objB.publicdateA;    //ok:基类的公共成员在派生类中为公共成员,对对象可见
 
    C objC;
    a=objC.privatedateA;   //error:基类中私有成员在派生类中是不可见的,对对象不可见
    a=objC.protecteddateA; //error:基类的保护成员在派生类中为私有成员,对对象不可见
    a=objC.publicdateA;    //error:基类的公共成员在派生类中为私有成员,对对象不可见
 
    D objD;
    a=objD.privatedateA;   //error:基类中私有成员在派生类中是不可见的,对对象不可见
    a=objD.protecteddateA; //error:基类的保护成员在派生类中为保护成员,对对象不可见
    a=objD.publicdateA;    //error:基类的公共成员在派生类中为保护成员,对对象不可见
 
    return 0;
}

2.关于子类型的描述中,( C)是错误的?
A.在公有继承下,派生类是基类的子类型
B.子类型关系是不可逆的
C.子类型就是指派生类是基类的子类型
D.一种类型当它至少提供了另一种类型的行为,则这种类型是另一种类型的子类型

解释:该题涉及到了子类型的概念:子类型必须是子类继承了父类的所有可继承特性,也即公有继承,才能说是子类型,否则就只是单纯的子类。公有继承下派生类为基类的子类型,其他都只是子类。

    3.C++类的继承中构造函数和析构函数调用顺序

这个比较困难,通过一个程序来学习:

/*当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的
构造函数,依次类推,直至到达派生类次数最多的派生次数最多的类的构造函数为止。
简而言之,对象是由“底层向上”开始构造的。因为,构造函数一开始构造时,总是
要调用它的基类的构造函数,然后才开始执行其构造函数体,调用直接基类构造函数时,
如果无专门说明,就调用直接基类的默认构造函数。在对象析构时,其顺序正好相反。
下面的这个程序说明这个问题*/
//-------------------------------------------------
#include <iostream>
using namespace std;
class Shape
{
public:
void Draw() {cout<<"Base::Draw()"<<endl;}
void Erase() {cout<<"Base::Erase()"<<endl;}
Shape() {Draw();} //基类构造函数,调用上面的Draw函数体
virtual ~Shape() {Erase();}//基类析构函数,调用上面的Erase函数体
};
//-------------------------------------------------
class Polygon:public Shape
{
public:
Polygon() {Draw();}
void Draw() {cout<<"Polygon::Draw()"<<endl;}
void Erase() {cout<<"Polygon Erase()"<<endl;}
~Polygon() {Erase();}
};
//--------------------------------------------------
class Rectangle:public Polygon
{
public:
Rectangle() {Draw();}
void Draw() {cout<<"Rectangle::Draw()"<<endl;}
void Erase() {cout<<"Rectangle Erase()"<<endl;}
~Rectangle() {Erase();}
};
//--------------------------------------------------
class Square:public Rectangle
{
public:
Square() {Draw();}
void Draw() {cout<<"Square::Draw()"<<endl;}
void Erase() {cout<<"Square Erase()"<<endl;}
~Square() {Erase();}
};
//--------------------------------------------------
int main()
{
Polygon c;
Rectangle s;
Square t;
cout<<"------------------------------------------"<<endl;
return 0;
}
//------------------------------------------
运行结果:
Base::Draw()
Polygon::Draw()
Base::dRAW()
Polygon::Draw()
Rectangle::Draw()
Base::dRAW()
Polygon::Draw()
Rectangle::Draw()
Square::Draw()
------------------------------------------
Square Erase()
Rectangle Erase()
Polygon Erase()
Base::Erase()
Rectangle Erase()
Polygon Erase()
Base::Erase()
Polygon Erase()
Base::Erase()
Press any key to continue
题库的题,随便看看~
4.没有指明访问权限的类成员,其访问权限默认为( B )。
A.公有访问权限 B.私有访问权限
C.保护访问权限 D.不能确定?

5.关于构造函数的说法,下面不正确的是(A)。
A.如果类中没有定义默认构造函数,则系统会为该类生成一个默认构造函数。
B.默认的构造函数没有参数。
C.构造函数在对象创建时被自动调用。
D.构造函数没有返回值。
解释:应该是类中没有定义任何构造函数,系统才会为该类生成一个默认的构造函数

6.关于析构函数,下列说法错误的是(C)。
A.析构函数没有参数
B.析构函数没有返回值
C.析构函数可以重载
D.如果没有定义类的析构函数,系统会帮我们创建一个析构函数。
解释:C:一个类中只能定义一个析构函数,否则会造成同一个对象的多次删除,而构造函数可以根据不同的参数和类型进行多次重载


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值