C++中子类的变量能不能覆盖父类的变量?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中子类的变量能不能覆盖父类的变量?相关的知识,希望对你有一定的参考价值。
刚学了继承技术,还不太清楚一些东西。比如下面代码:
#include <string>
#include <iostream>
using namespace std;
class Parent
public:
Parent() :mStr("Parent") ;
virtual void Show();
protected:
string mStr;
;
class Children : public Parent
public:
Children() : mStr("Children");
protected:
string mStr;
;
void Parent::Show() cout<<mStr<<endl;
int main(int argc, char* argv[])
Children tmp;
tmp.Show();
return 0;
我本来预想上面的代码会显示"Children",但是结果是"Parent"。
然后把 cout<<mStr<<endl; 改为了 cout<<this->mStr<<endl; ,但是结果一样。
尝试给变量mStr加上 virtual 关键字,但是编译不通过。
如果把父类的Show函数写为虚函数,那么子类覆盖的代码是一模一样的,又不符合继承的优点。
那么究竟要怎么做才好?
1 子类和父类没有同名成员变量。
此种情况下不会出现任何情况的覆盖。
2 在父类中,有virtual修饰的虚成员变量,在子类中有与其同名同类型的成员变量。
此种情况下,子类变量会覆盖父类变量。
3 在父类中,存在有与子类同名同类型的成员变量,但没有virtual修饰。
此时不会覆盖,但是会重写。即子类中访问成员变量时,访问的是子类的,父类的会被隐藏。但是通过父类名直接调用仍可以使用父类该变量。不属于覆盖,被称为重写。 参考技术A 子类的mStr和父类的mStr是不同的东西,你在子类中调用:
mStr
this->mStr
都是子类的变量,
Parent::mStr
才是父类的变量。
#include <assert.h>
class Parent
public:
Parent() : m_nVal(0)
virtual void Show()
assert(m_nVal == 0);
protected:
int m_nVal;
;
class Son : public Parent
public:
Son() : m_nVal(1)
virtual void Show()
assert(Parent::m_nVal == 0);
assert(m_nVal == 1);
assert(this->m_nVal == 1);
private:
int m_nVal;
;
int _tmain(int argc, _TCHAR* argv[])
Son s;
s.Show();
return 0;
参考技术B 是可以的,因为子类和父类有不同的作用域 参考技术C 从内存分配的角度上来看,子类继承时,先分配了父类的内存,再分配子类的内存,所以子类中同时存在着父类的空间和新的空间两个部分。当你使用父类函数的时候,显然会使用的是父类中的变量。在子类中增加同名的变量,会使子类的成员变量将父类的覆盖,却不会使父类的函数中的成员发生覆盖。
所以最好的办法就是不在子类中增加新的变量,而是直接使用父类中的变量。
将
Children() : mStr("Children");
protected:
string mStr;
改为
Children() mStr = "Children";追问
如果mStr被定义为常量那怎么办?
或者说父类中的一个函数被不同的子类使用,而此函数需要使用 对应不同子类的不同常量。
~呃~ 如果一定要父类使用子类的变量的话,在父类的成员函数中增加一个传参的函数,构造函数里面使用它从子类传入参数。这样子也不是很方便的,还不如重载一个函数。
总之,父类使用子类的变量是很少用的,不同的子类有不同的要求尽量用重载函数的形式使用。
如果均相同就如我一开始讲的方法。
以上是关于C++中子类的变量能不能覆盖父类的变量?的主要内容,如果未能解决你的问题,请参考以下文章