对C++虚函数使用的深刻体会,以及覆写,重载的区别?

虚函数就是实现函数的覆写,

它们以下特点:

(1)不同的范围(分别位于派生类与基类); 
(2)函数名字相同; 
(3)参数相同; 
(4)基类函数必须有virtual关键字

 

还有,要注意一点,函数的返回值是影响不了覆写和重载函数的.

 

 

我的以下程序,思路 不对的地方就是没能完全理解多态的应用,

#include <iostream> 
#include <vector> 
#include <string> 
using namespace std;

class A 
{

};

class BA: public A 

public: 
int m_i; 
int getValue()
{
 return m_i;
}
};

class CA: public A 

public: 
string m_str; 
string getValue()
{
 return m_str;
}
};

class DA : public A 

public: 
vector <A *> m_vec; 
};


int main() 

BA *pBa = new BA; 
pBa->m_i = 100;

CA *pCa = new CA; 
pCa->m_str = "myprogram";

DA da; 
da.m_vec.push_back(pBa); 
da.m_vec.push_back(pCa);

 

 

 

//请问一下,我要在这里输出da.m_vec的所有内容,应该如何实现呢?

vector<A *> :: iterator it;

for (it = da.m_vec.begin(); it != da.m_vec.end(); it++)

{

  (*it)->getValue();   // error,其类A没有该虚函数实现.

}

 


return 0; 

在以上程序中, CA的string getValue()函数和BA的int getValue()函数即使加了virtual ,也不能成为多态,一是基类A没有相应的虚函数,二是int 和string的返回类型不一致.因此,在实现输出的话,需要在A类中写一个纯虚函数,然后在各自的子类上覆写该虚函数,写上分别的实现即可.

 

因此,可以写成下面的样子:

#include <iostream> #include <vector>
#include 
<string>
using namespace std;

class A
{
public:
void pout() { doout(); }

virtual void doout()=0;
};

class BA: public A
{
public:
    
void doout() { cout<<m_i<<" "; }
    
int m_i;
};

class CA: public A
{
public:
    
void doout() { cout<<m_str<<" "; }
    
string m_str;
};

class DA : public A
{
public:
    
void doout() {
        
for (vector<*>::iterator it=m_vec.begin();it!=m_vec.end();++it)
          (
*it)->doout();
    }
    vector 
<*> m_vec;
};


int main()
{
    BA 
*pBa = new BA;
    pBa
->m_i = 100;

    CA 
*pCa = new CA;
    pCa
->m_str = "myprogram";

    DA da;
    da.m_vec.push_back(pBa);
    da.m_vec.push_back(pCa);

    da.doout();


    
return 0;
}

下面的网友邦的建议:

不要用这样的语句 
cout < < ((A *)(it))->getValue() < < endl; 

由于返回类型不一致,很难在基类里声明。把输出功能,放到派生类里去,用一个基类虚函数调用。这样就可以*it.foo()来实现输出了。

是把输出放到派生类的虚函数定义中,在基类用一个非虚函数调用虚函数来实现输出。

 

 =============================================================================================================

以下是重载和覆写的区别?(网上搜到的,转)

 

重载和覆写有什么区别?

 

重载有对于已有的方法或操作符进行重构,方法被重载后可以通过其重载的形式或方法原形来调用,有几个重载就有几个调用的形式;操作符重载后会变成你重构的定义. 
而覆写则是将之前的方法进行隐藏

 

重载提供了对一个方法签名的不同参数调用的实现。 
覆写提供了子类中改变父类方法行为的实现。

 

其实很本质的区别就是看函数特征:覆写(Override)的两个函数的函数特征相同,重载(Overload)的两个函数的函数名虽然相同,但函数特征不同。 
函数特征包括函数名,参数的类型和个数。 
Override 是在继承的时候,如果你写的函数与要继承的函数函数特征相同,那么,加上这个关键字,在使用这个子类的这个函数的时候就看不见父类(或超类)的函数了,它被覆盖掉了。 
比如:Derived继承了Base,Base里面有void A(int a) 
那么如果你Derived里面觉得A写得不好或不适合这个类,你想重新再写一遍A里的代码,那么就写override void A(int a)这样,原来的那个函数就被你新写的这个覆盖掉了。 
Overload 是重载,就是说函数名相同,函数特征不同,系统会根据你提供的参数来调相应的函数。 
比如:void A(int a)和void A(int a,int b) 
如果你用的是A(1)那么调的是第一个,如果是A(1,1)那么调的是第二个。 

都说的好,重载和覆盖还有个关键区别就是: 
重载的既可以是父类的方法也可以是子类的方法(虽然名字相同但是参数不同) 
而覆盖就是在子类中定义一个和父类一样的方法(关键是名字和参数都是一样的),用中文覆盖来说明这种现象是在好不过了。。。。。。。

 

 

重载与覆盖 
成员函数被重载的特征: 
(1)相同的范围(在同一个类中); 
(2)函数名字相同; 
(3)参数不同; 
(4)virtual关键字可有可无。 
覆盖是指派生类函数覆盖基类函数,特征是: 
(1)不同的范围(分别位于派生类与基类); 
(2)函数名字相同; 
(3)参数相同; 
(4)基类函数必须有virtual关键字

举例说明:
覆写(overriding):
class A {
  System.out.println("This is class A");
}

class B extends A {
  System.out.println("This is class B");
}

重载(overloading):
class C {
  void print(int i) {
    System.out.println(i);
  }
  void print(float f) {
    System.out.println(f);
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值