精华内容
下载资源
问答
  • 2022-03-09 09:21:34

    1、基类指针指向派生类对象
        同名同参函数,基类虚函数、派生类实函数
            只要调用该名字的函数,都是调用派生类函数
        同名同参函数,基类实函数,派生类虚函数
            只要调用该名字的函数,都是调用基类函数
                
        同名同参函数,基类虚函数,派生类虚函数
            只要调用该名字的函数,都是调用派生类对象
        同名同参函数,基类实函数,派生类实函数
            只要调用该名字的函数,都是调用基类函数
        
        得出结论:基类指针pBase指向派生类对象basePlus时,
        基类与派生类都含有同名同参函数,如果是一虚一实,
        pBase调用他们中的实函数;如果同实,调用基类函数;
        同虚,调用派生类函数
        注:如果是一定要调用基类的函数,可以使用pBase::func
            如果是一定要调用派生类函数,可以使用basePlus::func,只能在派生类中调用,基类不能调用
            
        一般是同实同虚。

    更多相关内容
  • 基类指针指向派生类对象

    千次阅读 2021-06-20 15:06:25
    基类指针指向派生类对象,只能调用基类原有的,而不能调用派生类中的 从pa=&b,这里可看出,解释一下:这里取得是b的首地址,而pa的长度是由数据类型的内存所占大小决定的 pb=&a 的话是会报错的,因为pb的...

    在这里插入图片描述
    A作为基类,B作为派生类
    基类指针指向派生类对象,只能调用基类原有的,而不能调用派生类中的
    从pa=&b,这里可看出,解释一下:这里取得是b的首地址,而pa的长度是由数据类型的内存所占大小决定的
    pb=&a 的话是会报错的,因为pb的长度已经超出了A的内存范围,多出的那一部分可能会乱指,导致安全性缺失
    当然pb->showA()也是会报错的,同样的道理。
    所以,派生类指针不能指向基类对象

    构造函数能定义为虚函数?
    不能,虚函数是需要通过对应的vtable虚指针来调用,而虚指针是在对象创建完毕才有的,但是构造函数是要在对象创建时调用,这之间无法同时达到要求,所以构造函数不能定义为虚函数。

    用基类的指针去指向对象,在析构时就会出现问题,因为派生类对象在析构时是先释放派生类,再释放基类(正确的做法),而用基类指针指向派生类对象,析构时是只析构基类(错误的做法),从而导致派生类的那一部分没有被释放掉,成为僵尸内存或称内存泄漏
    所以用基类指针指向派生类对象,要用virtual析构函数,使基类指针可以指向派生类中(virtual的作用:根据对象的实际类型,调用相应的类型函数。),使得再手动释放内存delete 时,可以调用派生类的析构函数,从而自动调用基类的析构函数。

    展开全文
  • 在写代码时:要求vector来实现多态性 , 用基类指针变量指向子类对象。 前面的父类和子类定义: //创建一个表示各种不同包裹的继承层次 #include <iostream> #include <algorithm> #include <...

    添加问题:

    练手创建一个表示各种不同包裹的继承层次。

    在写代码时:要求vector来实现多态性 , 用基类指针变量指向子类对象。


      前面的父类和子类定义:

    //创建一个表示各种不同包裹的继承层次 
    #include <iostream>
    #include <algorithm>
    #include <vector> 
    #include<iomanip>//输出对齐头文件 
    using namespace std;
     
    struct people     //定义结构体存寄/收件人信息 
    {
    	string name;   //姓名 
    	string state;       //省
    };
    
    class Package   //基类
    {
    private: 
    	struct people sender;  //代表寄件人
    	struct people rec;  //收件人信息 
    	double unit_cost;     //每盎司费用 
    
    public:
    	double weight;    //存储包裹重量(以盎司计)
    	double calculateCost();
    	Package(struct people,struct people,double,double);    //构造函数 
    	string Getsender();   //获得发送者的地址信息 
    	string Getrecname();      //获得接收者的地址信息 
    	double GetWeight();   //获得包裹重量,以供派生类使用 
    	double GetCostPerOunce();      //获得每盎司费用,以供派生类使用 
    };
    
    //构造函数
    Package::Package(struct people sender_,struct people rec_,double unit_cost_,double weight_):sender(sender_),rec(rec_),unit_cost(unit_cost_),weight(weight_)//初始化这些值 
    {	
    	weight=weight_>0?weight_:1;      //确保重量为正值 
    	unit_cost=unit_cost_>0?unit_cost_:1;      //确保每盎司费用为正值 
    }
    
    double Package::calculateCost()
    {
    	double sum_cost;
    	sum_cost=weight*unit_cost;
    	return sum_cost;
    }
    
    string Package::Getsender()    //获得发送者的地址信息,以供派生类使用 
    {
    	return sender.state;
    }
    
    string Package::Getrecname()    //获得接收者的地址信息,以供派生类使用 
    {
    	return rec.state;
    }
    
    double Package::GetWeight()     //获得包裹重量,以供派生类使用
    {
    	return weight;
    }
    
    double Package::GetCostPerOunce()    //获得每盎司费用,以供派生类使用 
    {
    	return unit_cost;
    }
    
    //派生类 
    class TwoDayPackage:public Package    //两日包裹类
    { 
    public:
    	TwoDayPackage(struct people,struct people,double,double,double);   //构造函数 
    	double calculateCost();
    private:
    	double normal_send_fee;     //平寄费 
    };
    //构造函数
    TwoDayPackage::TwoDayPackage(struct people sender_,struct people rec_,double unit_cost_,double normal_send_fee_,double weight_):Package(sender_,rec_,unit_cost_,weight_),normal_send_fee(normal_send_fee_)
    {
    }
    
    double TwoDayPackage::calculateCost()    //TwoDayPackage类重新定义基类的成员函数 calculateCost来计算运输费用 
    {
    	return normal_send_fee+Package::calculateCost();       //平寄费加由基类Package的calculateCost函数计算得到的基于重量的费用
    } 
    
    //连夜包裹类
    class OvernightPackage:public Package
    {
    public:
    	OvernightPackage(struct people,struct people,double,double,double);  //构造函数 
    	double calculateCost();
    private:
    	double normal_per_ounce_fee;  //付给连夜快递服务的每盎司额外费用 
    };
    
    //构造函数
    OvernightPackage::OvernightPackage(struct people sender_,struct people rec_,double unit_cost_,double normal_per_ounce_fee_,double weight_):Package(sender_,rec_,unit_cost_,weight_),normal_per_ounce_fee(normal_per_ounce_fee_)
    {
    } 
    
    
    double OvernightPackage::calculateCost()       //OvernightPackage类重新定义基类的成员函数 calculateCost来计算费用
    {
    	return GetWeight()*(normal_per_ounce_fee+GetCostPerOunce());      //平寄费加由基类Package的calculateCost函数计算得到的基于重量的费用
    } 
    

    main()中:

    	//vector来实现多态性 	
    	vector<Package *>vec(2);//包含package指针的vector对象,指针指向 twodaypackage对象和 overnightpackage对象 
    	//基类指针变量指向子类对象    
        vec[0]=new TwoDayPackage(sender,rec,0.5,5,sender_weight);// 包裹2.5盎司,每盎司0.5元,平寄费5元, 返回值5+2.5x0.5=6.25元
        vec[1]=new OvernightPackage(sender,rec,0.5,0.2,sender_weight);//包裹2.5盎司,每盎司0.5元,连夜快递每盎司额外费用0.2元,返回值 2.5x(0.5+0.2)=1.75元
    	cout<<endl;

    调用方式:

    //调用每个Package的calculateCost成员函数并输出结果 
    	//跟踪记录该vector中所有Package的总的运输费用,并在循环遍历结束时显示此总费用 
    	double sumcost=0;//总的运输费用 
    	for(int i=0;i<vec.size();i++)
    	{
    		double cost=vec[i]->calculateCost(); 
    	
    		if(i==0)
    			cout <<"twodaypackage类所需费用为:"<<cost<< endl;
    		else
    			cout <<"overnightpackage类所需费用为:"<<cost<< endl; 
    		sumcost+= cost;
    	} 
    	cout<<"该vector中所有Package的总的运输费用为:"<<sumcost<<endl; 

    然而出现了调用的结果仍是基类中calculateCost()函数的情况。最后了解了有关虚函数的定义。

    进行了修改。

    解决方式:

    修改了Package的基类

    class Package   //基类
    {
    private: 
    	struct people sender;  //代表寄件人
    	struct people rec;  //收件人信息 
    	double unit_cost;     //每盎司费用 
    
    public:
    	double weight;    //存储包裹重量(以盎司计)
    	virtual double calculateCost();
    	Package(struct people,struct people,double,double);    //构造函数 
    	string Getsender();   //获得发送者的地址信息 
    	string Getrecname();      //获得接收者的地址信息 
    	double GetWeight();   //获得包裹重量,以供派生类使用 
    	double GetCostPerOunce();      //获得每盎司费用,以供派生类使用 
    };
    

    添加了virtual关键词。

    virtual double calculateCost();

    此时为同名同参函数,基类虚函数、派生类实函数,故后续调用都是调用派生类函数。

    暂时还是不太熟练 同名同参条件下,基类和派生类都能调用的通用情况,后续在学习吧。

    借鉴理论参考:(非常感谢CSDN博主「why you so」的原创文章)

    原文链接:https://blog.csdn.net/qq_38650447/article/details/123368853

    1、基类指针指向派生类对象
        同名同参函数,基类虚函数、派生类实函数
            只要调用该名字的函数,都是调用派生类函数
        同名同参函数,基类实函数,派生类虚函数
            只要调用该名字的函数,都是调用基类函数
                
        同名同参函数,基类虚函数,派生类虚函数
            只要调用该名字的函数,都是调用派生类对象
        同名同参函数,基类实函数,派生类实函数
            只要调用该名字的函数,都是调用基类函数
        
        得出结论:基类指针pBase指向派生类对象basePlus时,
        基类与派生类都含有同名同参函数,如果是一虚一实,
        pBase调用他们中的实函数;如果同实,调用基类函数;
        同虚,调用派生类函数
        注:如果是一定要调用基类的函数,可以使用pBase::func
            如果是一定要调用派生类函数,可以使用basePlus::func,只能在派生类中调用,基类不能调用
            
        一般是同实同虚。

    展开全文
  • 1,如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(静态联翩) 2,如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很...

    父类子类指针函数调用注意事项
    1,如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(静态联翩)
     

    2,如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很危险,也不符合生活习惯,在程序设计上也会给程序员带来困扰。(一般不会这么去定义)
     

    3,如果基础类和衍生类定义了相同名称的成员函数,那么通过对象指针调用成员函数时,到底调用那个函数要根据指针的原型来确定,而不是根据指针实际指向的对象类型确定。
     

    虚拟函数就是为了对“如果你以一个基础类指针指向一个衍生类对象,那么通过该指针,你只能访问基础类定义的成员函数”这条规则反其道而行之的设计。
     

    如果你预期衍生类有可能重新定义一个和父类一样原型的成员函数,那么你就把它定义成虚拟函数( virtual )。

    polymorphism就是让处理基础类别对象的程序代码能够通透的继续适当地处理衍生类对象。


    纯虚拟函数:

    virtual void myfunc ( ) =0;

    纯虚拟函数不许定义其具体动作,它的存在只是为了在衍生类钟被重新定义。只要是拥有纯虚拟函数的类,就是抽象类,它们是不能够被实例化的(只能被继承)。如果一个继承类没有改写父类中的纯虚函数,那么他也是抽象类,也不能被实例化。

    抽象类不能被实例化,不过我们可以拥有指向抽象类的指针,以便于操纵各个衍生类。

    虚拟函数衍生下去仍然是虚拟函数,而且还可以省略掉关键字“virtual”。

    构造函数

    1. 在构造函数中调用虚函数,调用的是自己类的虚函数,如果调用纯虚函数,由于没有定义,会报错。

    析构函数

    1. 通过子类对象的指针删除子类对象时,无论父类的析构函数是不是虚的,都会调用父类的析构函数。但是通过父类对象的指针(指向子类对象)删除对象时,如果父类的析构函数不是虚的,那么就不会调用子类的析构函数。所以为了保证正确性,要将会被派生的类的析构函数声明为虚的。

    虚函数与默认参数

    1. 虚函数重载时,子类修改了父类的缺省的参数值 ,那么将根据指针本身的类型来决定缺省参数的值,但是调的函数还是有虚函数作用的,即对象实际是什么类型将调用它所对应的函数。
      用一句话来解释原因就是:虚函数是动态绑定的(dynamically bound),但是缺省参数却是静态绑定的(statically bound)。

    const

    1. 函数加上const修饰与不加const,实际上声明了两个不同的函数。所以在父类中加上const,但是子类同名同参的函数没有加const,他们是两个不同的接口,此时虚函数没有被重载。
    展开全文
  • 基类指针指向派生类,函数f()在基类和派生类皆为虚,故动态编联指向派生类,输出B::f(); (2)第二部分实际是 const A* a = new B(); 本质还是基类指针指向派生类,并且由于a为常指针,只能指向常函数,所以肯定是...
  • 基类指针指向派生类对象、派生类指针指向基类对象 以下代码运行后的输出结果是() #include using namespace std; class A { public: void virtual print() { cout << "A" << endl; } }; class ...
  • 为什么需要基类指针指向派生类对象? 我们知道虚函数可以让我们的类具备多态的功能,你肯定在此会有所疑惑,为什么需要基类指针指向派生类对象?派生类指针自己就能实现的功能,何必用基类指针来多此一举呢?其实这...
  • C++基类指针指向派生类(指针)

    千次阅读 2019-11-27 15:45:45
    我们常用基类指针指向派生类对象来实现多态性。 基类指针只能访问到基类中含有的公有成员。 成员如果是数据成员的话访问的是基类的版本(如果派生类中含有相同名字的数据成员的话)。 对于已经被重写的方法成员...
  • 基类指针pBase指向派生类对象basePlus,基类与派生类含有同名同参的函数,pBase调用函数应该调用哪个,当函数有虚函数时又该调用哪个? 先上结论: 基类指针pBase指向派生类对象basePlus时,基类与派生类都含有...
  • //基类指针指向派生类,居然同时改变基类及对应派生的成员值 //基类指针能获取派生成员值,用基类成员函数改变派生类成员值 #include<iostream> using namespace std; class B; class A{ private: int a; ...
  • (基类指针指向派生类对象)1. 指向基类的指针可以指向派生类对象,当基类指针指向派生类对象时,这种指针只能访问派生对象从基类继承而来的那些成员,不能访问子类特有的元素,除非应用强类型转换,例如有基类B和从B...
  • 假设基类(父类)是Base,派生类(子类)是...但实际上这是错误的,这样得到的派生类指针是不能指向派生类的成员函数或者数据成员。 而应该使用reinterpret_cast强制类型转换进行转换。 Derived d; Base *bp =...
  • 在基类与派生类之间,有一个规定:派生类对象的地址可以赋给指向基类对象的指针变量(简称基类指针),即基类指针也可以指向派生类对象。为什么有这一规定呢?因为它可以实现多态性【1】,即向不同的对象发送同一个...
  • 一道C++面试题 ...而刚才得出7的结果,是因为我们根本没用到多态,相当于new了一个Derived指针指向派生类,得出的自然是派生类自己应该得出的结果。 永远不要在派生类中改变虚函数的默认参数值
  • 基类指针指向派生类对象(C++,虚函数,内存泄漏),也称作父类指针指向子类对象
  • 前一个问题是:非多态情况下,用基类指针去访问派生类的函数。 那么又要问了:多态情况下,怎么用基类指针去访问基类的函数呢?当然这里指的是虚函数。 答案是:用取内容运算符*获得派生类对象,然后再强制转换成...
  • A.h#ifndef A_H#define A_Hclass A{public: virtual void a(); virtual void b(); virtual void c();};#endifA.cpp#include &lt;iostream&gt;using std::cout;using std::endl;#include "...
  • 基类指针指向派生类

    2013-09-15 21:15:58
    也就是说,当基类中析构函数是虚函数时,如果基类指针指向派生类对象,当销毁派生类对象时,就会先调用派生类的析构函数,然后再调用基类的析构函数。但如果基类析构函数没有使用virtual,即如果不是虚析构函数,...
  • 结论: ①声明为指向基类对象的指针可以指向它的公有派生的对象,但是不允许指向它的私有派生的对象...(只适用于基类指针指向派生类对象,不能反过来操作) 结论①的代码示例: 结论②的代码示例: ...
  • //基类指针指向派生类对象 pa->F1(); pa->F2(); pb =(B *) &TA;//派生类指针指向基类对象 pb->F1(); pb->F2(); } 以上程序输出结果: B1 A2 A1 B2 解释一下: 一个类所有的函数都是再code代码区中唯一的...
  • 函数重载、函数隐藏、函数覆盖函数重载只会发生在同作用...函数隐藏是指派生类中函数与基类中的函数同名,但是这个函数在基类中并没有被定义为虚函数,这种情况就是函数的隐藏。 所谓隐藏是指使用常规的调用方法,派...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 61,599
精华内容 24,639
关键字:

基类指针指向派生类