C++7.18

多态:

1、多态形成的条件:

1、必须有类的继承关系;

2、继承关系中用同名虚函数;

3、必须有基类指针;

2、多态体现在,基类指针有很多的表现方式;例如:

class A{};

class B:public A{};

 

int main()

{

A *ptr=new B;

}

这里我们定义两个类,基类A和派生类B,在主函数中,定义了一个基类指针ptr;指向了B这个派生类。那么这个指针就可以访问 从A继承的pubic函数。

这里又涉及到一个遮蔽的问题;

例如:

class A{

public

virtual void say()

};

class B:public A{

public:

virtual void say()

void print()

};

 

int main()

{

A *ptr=new B;

ptr->say();

}

这边 ptr->say调用的函数,就是B中遮蔽了基类A的函数SAY,如果说B中没有SAY这个函数那么,系统会往上层寻找,一直到找到这个函数,比如这里的程序,如果B没有,那么就会调用A里面的SAY;如果没有的话那么就报错。

此外,基类指针是没办法访问,它指向的类的本身的函数的,例如上面的函数,ptr->print()这个函数是没有办法访问的,会报错:class A中没有这个函数。

#include <iostream>

 

using namespace std;

 

class A{

protected:

    char *name;

    char *sex;

public:

    A(char*,char*);

    void virtual say();

    void pr();

};

A::A(char *n,char *s):name(n),sex(s){}

void A::pr()

{

    cout<<"i am a"<<endl;

}

void A::say()

{

    cout<<name<<" 性别是"<<sex<<endl;

}

 

class B:public A{

protected:

    float score;

public:

    B(char *,char *,float);

    void virtual say();

    void print();

};

 

B::B(char *n,char *s,float sc ):A(n,s),score(sc){}

void B::print()

{

   cout<<name<<" "<<sex<<"成绩是"<<score<<endl;

}

 

int main()

{

    A *pt=new A("xiaoming","male");

    pt->say();

    pt=new B("xiaoli","female",89.5);

  pt->print();

    pt->say();

    pt->pr();

    return 0;

}

在这个函数中,定义了一个基类A的指针pt 初始化了,然后调用的SAY这个函数,再把这个基类指针给了 B类,调用B类的函数say(),在这里调用Print是错误的,因为class A中没这个虚函数,pt指向了B 调用了pr系统在B中没有找到这个函数,去基类A中寻找找到了,所以调用A中函数Pr();就输出了 i am a这个句子。

虚函数和多态的意义在与,可以使一个指针进行多样化操作。使一个指针有了很多种变化。

总结:有继承关系的两个类中,两个函数完全相同,在基类中定义成虚函数,基类指针对不同的类进行指向,然后就可以访问内容不同同名虚函数。

**函数需要是无论返回值,形参,函数名都一样的两个函数。

 

2、析构函数需要改为虚函数吗?

直接看代码:#include <iostream>

 

using namespace std;

 

class A{

private:

    char *m_name;

public:

    A();

    virtual ~A();

};

A::A()

{

    m_name=new char [20];

    cout<<"A 1"<<endl;

}

 

A::~A()

{

    delete [] m_name;

    cout<<"A 2"<<endl;

}

 

class B:public A

{

private:

    char *id;

public:

    B();

    ~B();

};

B::B()

{

    id =new char [20];

    cout<<"B 1"<<endl;

       }

int main()

{

    A *k=new B;

    delete k;

}

 

在这个函数中,如果我们不把析构函数 设置成虚析构的话,那么运行结果是,A构造,B构造,A析构。B并没有析构,我们在构造函数中请求了20个字节的空间在堆上,如果不析构那么长时间的话就会出现内存泄露问题。所以我们需要在A的析构函数前面加上 virtual 虚函数的修饰,这样B类就会被析构了。

 

4、纯虚函数

纯虚函数是指,在基类中定义了函数,但是在函数后面加了=0”,这样函数就变成了纯虚函数,例如:

class A{

public:

int area()=0;

};

这里的area函数就是一个纯虚函数

纯虚函数在使用是需要注意,需要在派生类中,对所有的纯虚函数进行申明定义后才能,才能定义对象。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值