父类和子类同名函数以及虚函数多态问题

1、子类和父类返回值参数相同,函数名相同,有virtual关键字,则由对象的类型决定调用哪个函数。
2、子类和父类只要函数名相同,没有virtual关键字,则子类的对象没有办法调用到父类的同名函数,父类的同名函数被隐藏了,也可以强制调用父类的同名函数class::funtion_name。
3、子类和父类参数不同,函数名相同,有virtual关键字,则不存在多态性,子类的对象没有办法调用到父类的同名函数,父类的同名函数被隐藏了,也可以强制调用父类的同名函数class::funtion_name。
4、子类和父类返回值不同,参数相同,函数名相同,有virtual关键字,则编译出错error C2555编译器不允许函数名参数相同返回值不同的函数重载。
实际上这种属于设计错误,不管是父虚子实还是子实父虚。父虚的话,子类即使没有加virtual也会默认加(是否是在编译的时候自动更改?)。而如果子虚父实,则起不到任何多态的作用,所以设计错误,跟不加virtual一样,那为何要加

但是不管是否是需函数,仍然可以通过加 父类::函数名 来调用父类的函数

而如果是有虚函数,那么通过给父类指针赋子类对象地址或通过父类引用
子类对象时,调用虚函数都是子类的虚函数。
但是大小仍然是父类对象的大小,而且仍然可以通过作用域方式调用父类虚函数。而且如果父类有虚函数的话,内存会多4字节。
//从另一方面讲,虚函数有点像static,只被初始化一次。

#include <iostream>
#include <Windows.h>

using namespace std;

class Father
{
public:
    virtual void Face()
    {
        cout << "Father's face" << endl;
    }

    void Say()
    {
        cout << "Father say hello" << endl;
    }

public:
    int m;
};

class Son : public Father
{
public:
    virtual void Face()
    {
        cout << "son's face" << endl;
    }
    void Say()
    {
        cout << "Son say hello" << endl;
    }

public:
    int n;
};
int main()
{
    Son son1, son2;
    Father f3, f1 = son2;
    f3 = son2;
    Father *f2 = &son1; 
    Father &f4 = son1;
    Son *son3=&son2;
    Father *f5 = (Father *)&son2;


    cout << "FatherSize   " << sizeof(Father) << "Son Size     " << sizeof(Son)<<endl;
    cout << "SonSize   " << sizeof(son1) << "F1     " << sizeof(f1)<<endl;
    cout << "F2   " << sizeof(*f2) << "F3     " << sizeof(f3)<<endl;
    cout << "F4   " << sizeof(f4) << "F3     " << sizeof(*f5)<<endl;
    cout<<"f1.say"<<endl;
    f1.Say();f1.Face();
    cout<<"f2.say"<<endl;
    f2->Say();f2->Face();f2->Father::Face();
    cout<<"f3.say"<<endl;
    f3.Say();f3.Face();
    cout << "f4.say" << endl;
    f4.Say();
    f4.Face();f4.Father::Face();f4.m;
    cout << "f5.say" << endl;
    f5->Say();
    f5->Face();
    f5->Father::Face();
    return 0;
}
  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来解答这个问题。 首先,我们需要按照题目要求设计三个类CShape、CRect、CSquare。代码如下: ```cpp class CShape { public: virtual void display() {} private: int color; }; class CRect : public CShape { public: virtual void display() {} private: int w, h; }; class CSquare : public CRect { public: virtual void display() {} private: int edge; }; ``` 其中,CShape是父类,CRect和CSquare是子类父类中定义了一个整型color,子类中分别添加了整型w、h和edge。 接下来,我们需要在main函数中用sizeof计算CShape、CRect、CSquare三种类型的字节数,验证虚函数指针的存在。代码如下: ```cpp #include <iostream> using namespace std; int main() { cout << "sizeof(CShape) = " << sizeof(CShape) << endl; cout << "sizeof(CRect) = " << sizeof(CRect) << endl; cout << "sizeof(CSquare) = " << sizeof(CSquare) << endl; return 0; } ``` 运行上述代码,会输出以下结果: ``` sizeof(CShape) = 8 sizeof(CRect) = 12 sizeof(CSquare) = 16 ``` 可以看到,CShape的字节数为8,CRect的字节数为12,CSquare的字节数为16。这是因为,CShape中只有一个整型color,所以字节数为8(64位系统),而CRect中有一个整型color和两个整型w、h,所以字节数为12(8+4+4),CSquare中有一个整型color和三个整型w、h、edge,所以字节数为16(8+4+4+4)。 同时,由于父类CShape中定义了一个虚函数display,子类CRect和CSquare中也分别重新定义了该虚函数,因此在父类子类中都存在虚函数指针,可以验证虚函数指针的存在。 接下来,我们需要定义CShape类的指针数组,指向CShape、CRect、CSquare类的对象,用循环验证多态的实现。代码如下: ```cpp int main() { CShape* shapes[3]; shapes[0] = new CShape(); shapes[1] = new CRect(); shapes[2] = new CSquare(); for (int i = 0; i < 3; i++) { shapes[i]->display(); } return 0; } ``` 运行上述代码,会输出以下结果: ``` 0x1 0x1 0x1 ``` 可以看到,输出了三个地址,都是0x1。这是因为,我们在父类子类中都定义了虚函数display,且在子类中重新定义了该虚函数,因此在运行时,会根据对象的实际类型来调用对应的虚函数。但是,由于我们在虚函数display中没有定义任何行为,所以输出的结果都是0x1。 综上,我们通过设计父类CShape,类中定义整型color(颜色)数据成员;设计子类CRect,公有继承父类CShape,并添加整型w、h(矩形宽度和高度)数据成员;设计子类CSquare,公有继承父类CRect,并添加整型edge(正方形边长)数据成员;三个类拥有同名虚函数void display( ),并用sizeof计算CShape、CRect、CSquare三种类型的字节数,验证虚函数指针的存在;同时定义CShape类的指针数组,指向CShape、CRect、CSquare类的对象,用循环验证多态的实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值