C++类的继承和派生的题~~选B,大家帮我解释解释~

C++类的继承和派生的题~~选B,大家帮我解释解释~,第1张

选B的原因如下:

问题1:对象成员的问题

子类Derived中有2个成员b和j,而b是基类Base类型的对象,我们选来分析这个对象成员b

在C++中,我们要使用非默认的构造函数来初始化对象成员(注意:不一定是基类的对象成员,这里介绍的情况适合所有对象成员)则必须使用初始化列表才能实现,比如

class B{public: B(int i){} };

class A{public: B mb; };

在上面语句中看起来没有问题,但是当我们创建类A的对象时,比如A ma就会出错,就会出现类A的对象成员mb没有可用的默认构造函数的错误,原因就是在类A中的对象成员mb是使用的默认构造函数来初始化的,因此要使程序正确,必须把类A改为如下语句

class A{public B mb; A():mb(3){} }

使用初始化列表,调用类B的带有一个参数的构造函数初始化对象成员mb,当数整数3可以替换为任何类型相容的整数变量

问题2:继承的问题

在派生类中调用基类带参数的构造函数的方法:在派生类的构造函数中使用初始化列表的形式就可以调用基类带参数的构造函数初始化基类成员,如B():A(int i){},类B是类A的派生类。

原因如下:

如果派生类没有显示用初始化列表调用基类的构造函数时,这时就会用派生类的构造函数调用基类的默认构造函数,构造完基类后,才会执行派生类的构造函数函数体,以保证先执行基类构造函数再执行派生类构造函数的顺序,如果基类没有默认构造函数就会出错。

问题3:类中的普通成员

对于子类Derived中的整型变量成员j,这个不用解释了吧,很简单。

综上所述,所以能满足以上要求的答案只有B

Derived : : Derived (int t) : b(t), Base(t), j(t) { }

第一句b(t)表示使用类Base中还有一个参数的构造函数初始化子类Derived中的对象成员b(注意:这个对象成员不一定非要是基类对象成员),

第二句Base(t)表示调用基类中的带有一个参数的构造函数构造基类部分

第三句j(t)这个不解释,很简单,楼主应该懂。

所以答案A是错误的,因类基类Base没有默认构造函数,在子类中必须显示调用基类的非默认构造函数构造基类部分

答案C是错误的:因为子类中的对象成员b是没有默认的构造函数的,在C中没有明确使用初始化列表调用对象成员的非默认构造函数初始化对象成员b

称案D就错得更明显了:除了有答案A的错误之外,还要加上变量i并不是子类的成员变量的错误,因此变量i轮不到使用子类来初始化。

如果你还不是很理解的话,可以去本人的文库下载专题文现<C++类中的各种成员,嵌套类,友元,this指针专题>和<C++继承,虚函数与多态性专题>,里面有专门介绍,相信其他内容也会给你一些帮助

#include<iostreamh>

#include<mathh>

class Shape

{

public:

virtual void showData()=0;

virtual double reArea()=0;

virtual double reVolume()=0;

};

class TwoDimShape:public Shape

{

public:

void showData(){return ;};

double reArea(){return 0;};

double reVolume(){return 0;};

protected:

double Area;

double Volume;

};

class ThreeShape:public Shape

{

public:

void showData(){return ;};

double reArea(){return 0;};

double reVolume(){return 0;};

protected:

double Area;

double Volume;

};

class Circle:public TwoDimShape

{

public:

Circle(double r){showData(r);}

~Circle(){}

virtual void showData(double x){radiu=x;}

virtual double reArea(){return Area=314radiuradiu;}

virtual double reVolume(){return Volume=0;}

private:

double radiu;

};

class Ellipse:public TwoDimShape

{

public:

Ellipse(double r,double b){showData( r, b);}

~Ellipse(){}

void showData(double a,double b){Long=a,wild=b;}

double reArea(){return Area=2Longwild;}

private:

double Long;

double wild;

};

class Rectangle:public TwoDimShape

{

public:

Rectangle(double a,double b){showData(a,b);}

~Rectangle(){}

void showData(double a,double b){Long=a,wild=b;}

double reArea(){return Area=Longwild;}

private:

double Long;

double wild;

};

class Triangle:public TwoDimShape

{

public:

Triangle(double l,double h){showData(l,h);}

~Triangle(){}

void showData(double l,double h){Long=l,heigh=h;}

double reArea();

private:

double Long;

double heigh;

};

class Ball:public ThreeShape

{

public:

Ball(double r){showData(r);}

~Ball(){}

virtual void showData(double r){radiu=r;}

virtual double reArea(){return Area=4314radiuradiu;}

virtual double reVolume(){return Volume=(4/3)314radiuradiuradiu;}

private:

double radiu;

};

class Cylinder:public ThreeShape

{

public:

Cylinder(double r,double h){showData(r,h);}

~Cylinder(){}

virtual void showData(double r,double h){radiu=r,heigh=h;}

virtual double reArea(){return Area=2314radiuradiu+2314radiuheigh;}

virtual double reVolume(){return Volume=314radiuradiuheigh;}

private:

double radiu;

double heigh;

};

class RectangularParallelepiped:public ThreeShape

{

public:

RectangularParallelepiped(double a,double b,double c)

{showData(a,b,c);}

~RectangularParallelepiped(){}

virtual void showData(double a,double b,double c) {al=a,bl=b,cl=c;}

virtual double reArea(){return Area=2(albl+alcl+blcl);}

virtual double reVolume(){return Volume=alblcl;}

private:

double al,bl,cl;

};

void main() //计算圆,长方形等面积体积

{

double area=0,volume=0;

Shape pet;

Circle a(2);//求圆,初始化半径,剩下的自己修改啦,呵呵

pet=&a;

area=pet->reArea();

cout<<area<<endl;

}

//希望对你有用啦

D是错的,应该是在销毁派生类对象时,先调用派生类的析构函数,再调用基类的析构函数这跟盖房拆房一个道理,盖时肯定要先盖基础(相当于建立时先调用基类),再盖上面(再调用派生类)拆房时,肯定很从上面拆(先调用派生类的析构函数),再拆下面(再调用基类的析构函数)其实上面只有简单的解释,上面的调用是因为,若你先调用基类的析构函数,会把派生类正在用的一次资源销毁,因为此时派生类还没有被销毁,所以肯定会出现问题。

代码:

#include <iostream>

using namespace std;

class student {

public:

student(int _num,char _name,int _age) {

name = (char)malloc(strlen(_name)+1);

strcpy(name,_name);

num = _num;

age =_age;

};

void display(){

cout<<"num:"<<num<<endl;

cout<<"name:"<<name<<endl;

cout<<"age:"<<age<<endl;

};

~student(){

free(name);

};

private:

int num;

char name;

int age;

};

int main()

{

student s(1,"John",20);

sdisplay();

}

报错是因为出现了二义性语句,因为类D的对象n有两个公共基类A的副本,这里不知道是调用由类B继承来的A的副本还是由类C继承来的A的副本。

可以使用vitrual关键字创建虚基类解决这个问题。这样的话只会有一个副本。参考代码如下:

#include <iostream>

using namespace std;

class A{

public:

int n;

};

class B:public virtual A{};

class C:public virtual A{};

class D:public B,public C{

int getn(){return n;}

};

int main()

{

D d;

dn=10;

cout<<dn<<endl;

return 0;

}

派生类就是从一个类衍生出的类。

利用继承机制,新的类可以从已有的类中派生。那些用于派生的类称为这些特别派生出的类的“基类”。

基类说明:在C++中要定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员,我们称已存在的用来派生新类的类为C++基类,又称为父类。

基类表:基类表中存放各个基类名称

基类说明符:基类类体中类成员的访问说明符

扩展资料

在java的继承关系中,新的类称为子类,也叫派生类。

继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力,是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。

参考资料来源:百度百科-派生类

以上就是关于C++类的继承和派生的题~~选B,大家帮我解释解释~全部的内容,包括:C++类的继承和派生的题~~选B,大家帮我解释解释~、求一C++程序,要用上类和对象,构造函数,析构函数,继承与派生的知识编一个程序,谢谢!!、如果一个派生类继承两个基类。那这个程序调用构造函数和析构函数的顺等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10123381.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存