C++中子类的变量能不能覆盖父类的变量?

刚学了继承技术,还不太清楚一些东西。比如下面代码:#include<string>#include<iostream>usingnamespacestd;classPar... 刚学了继承技术,还不太清楚一些东西。比如下面代码:

#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函数写为虚函数,那么子类覆盖的代码是一模一样的,又不符合继承的优点。
那么究竟要怎么做才好?
展开
 我来答
风若远去何人留
推荐于2016-09-26 · 知道合伙人互联网行家
风若远去何人留
知道合伙人互联网行家
采纳数:20412 获赞数:450126
专业C/C++软件开发

向TA提问 私信TA
展开全部
区分成员变量情况,有以下几种情况:
1 子类和父类没有同名成员变量。
此种情况下不会出现任何情况的覆盖。
2 在父类中,有virtual修饰的虚成员变量,在子类中有与其同名同类型的成员变量。
此种情况下,子类变量会覆盖父类变量。
3 在父类中,存在有与子类同名同类型的成员变量,但没有virtual修饰。
此时不会覆盖,但是会重写。即子类中访问成员变量时,访问的是子类的,父类的会被隐藏。但是通过父类名直接调用仍可以使用父类该变量。不属于覆盖,被称为重写。
haibasan
推荐于2018-03-07 · TA获得超过3996个赞
知道大有可为答主
回答量:1683
采纳率:33%
帮助的人:830万
展开全部
从内存分配的角度上来看,子类继承时,先分配了父类的内存,再分配子类的内存,所以子类中同时存在着父类的空间和新的空间两个部分。当你使用父类函数的时候,显然会使用的是父类中的变量。在子类中增加同名的变量,会使子类的成员变量将父类的覆盖,却不会使父类的函数中的成员发生覆盖。
所以最好的办法就是不在子类中增加新的变量,而是直接使用父类中的变量。

Children() : mStr("Children"){};
protected:
string mStr;
改为
Children() {mStr = "Children"};
追问
如果mStr被定义为常量那怎么办?
或者说父类中的一个函数被不同的子类使用,而此函数需要使用 对应不同子类的不同常量。
追答
~呃~ 如果一定要父类使用子类的变量的话,在父类的成员函数中增加一个传参的函数,构造函数里面使用它从子类传入参数。这样子也不是很方便的,还不如重载一个函数。
总之,父类使用子类的变量是很少用的,不同的子类有不同的要求尽量用重载函数的形式使用。
如果均相同就如我一开始讲的方法。
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
星夜落尘
2013-04-28 · TA获得超过594个赞
知道小有建树答主
回答量:466
采纳率:0%
帮助的人:355万
展开全部
子类的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;
}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
淡若亲风
2015-09-19 · TA获得超过409个赞
知道小有建树答主
回答量:204
采纳率:0%
帮助的人:149万
展开全部
是可以的,因为子类和父类有不同的作用域
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式