子类和父类有相同的变量的问题

cvison 2008-12-22 07:52:26
刚开始学习c++,在学习到继承的时候,产生了这个疑惑。我看的书比较简单,没有介绍这方面的内容的。或者请推荐相关的书籍,多谢诶

对于成员函数,有所谓的继承、覆盖、隐藏。对于成员变量呢?例如:

class A
{
protected:
int m_data;
public:
int getData()const{return m_data;}
};

class B : public A
{
protected:
int m_data;
public:
int getData()const{return m_data;}
}

main()
{
B b;
b.getData();
b.A::getData();
}

问题:如果按照上面的定义 b.getData返回的是b.m_data; b.A::getData返回的是b.A::m_data
如果B中没有定义m_data,那么 b.getData返回的是b.A::m_data; b.A::getData返回的是b.A::m_data
如果B中没有定义getData,那么 b.getData返回的是b.A::m_data; b.A::getData返回的是b.A::m_data,b怎么调用自己的m_data啊。
如果A中的getData定义为virtual则 b.getData返回的是b.m_data; b.A::getData返回的是b.A::m_data

请问这个是怎么实现的啊?哪个函数调用那个变量是有什么规则么?

***********************************************************************
下面是一个更变态的

class A
{
protected:
int m_data;
public:
A(int data = 0){m_data = data;}
int getData()const{doGetData();}
virtual int doGetData(){return m_data;}
};

class B : public A
{
protected:
int m_data;
public:
B(int data =1){m_data = data;}
int doGetData()const{return m_data;}
};

class C:public B
{
protectd:
int m_data;
public:
C(int data = 2){m_data = data;}
};

main()
{
C c(10);
cout<<c.GetData()<<endl; /*1*/
cout<<c.A::GetData()<<endl;/*1*/
cout<<c.B::GetData()<<endl;/*1*/
cout<<c.C::GetData()<<endl;/*1*/

cout<<c.doGetData()<<endl;/*1*/
cout<<c.A::doGetData()<<endl;/*0*/
cout<<c.B::doGetData()<<endl;/*1*/
cout<<c.C::doGetData()<<endl;/*1*/

}
实在是头晕了,尤其是c.A::GetData()和c.A::doGetData()。请各位大侠帮忙看看。
...全文
499 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
ken_scott 2008-12-23
  • 打赏
  • 举报
回复
const //忘了const
return //忘了return
ken_scott 2008-12-23
  • 打赏
  • 举报
回复
[Quote=引用楼主 cvison 的帖子:]
尤其是c.A::GetData()和c.A::doGetData()。请各位大侠帮忙看看
[/Quote]

其实无论是c.A::GetData(),c.B::GetData(),c.GetData(),还是c.C::GetData(),由于只一个GetData();所以调用的都是A::GetData();而GetData()调用doGetData(),A中的doGetData()被B中的doGetData()重写了,所以调用的都是B::doGetData() /* 1 */

而doGetData()分别在A,B中有出现(写),c.A::doGetData()就不用说了,一定就是A中doGetData();/* 0 */
而其他的则都被B中的doGetData()重写了;调用的自然都是B::doGetData() /* 1 * /

还有一点题外话:上面的程序有几个错误的地方:
virtual int doGetData()const {return m_data;}  // class A
int GetData()const {return doGetData()} //class A
xtting_8984313 2008-12-23
  • 打赏
  • 举报
回复
建议:

c++对象模型 看虚拟指针部分
effective c++ 看名字隐藏部分
里面也会有访问域的一些说明(大概就是从当前所在的最小范围的作用域,逐层往块、类、父类、上层父类、namespace、全局作用域::一层网上找)。所以无论你如何定义,如果你分别定义的变量和函数,类的函数总是找自身类的对应对象,和继承就没有关系了。



而且lz里面那种继承而不写成virtual的形式,会被meyer鄙视的。不过对了解c++很有帮助。

andy_youyou 2008-12-23
  • 打赏
  • 举报
回复
c++primer
chenhongdalj 2008-12-23
  • 打赏
  • 举报
回复
似懂非懂
chenhongdalj 2008-12-23
  • 打赏
  • 举报
回复
先不说同名变量的问题,就是A::GetData();能这样访问吗?
只有A的静态成员函数才能这样访问啊!
iory_526 2008-12-23
  • 打赏
  • 举报
回复
A::a 和 B::a 一样么? 不一样,域不同,说白了,Aa, Ba, 这是两个变量。
继承里也是一样地。
「已注销」 2008-12-23
  • 打赏
  • 举报
回复
继承问题和虚函数问题。
记住虚函数是通过指针或者引用,然后还要这个函数是virtual,此时才能表现出多态。
SearchLife 2008-12-23
  • 打赏
  • 举报
回复
up
机智的呆呆 2008-12-22
  • 打赏
  • 举报
回复
函数所访问的变量在编译是已确定,调用时this+偏移~~~偏移是在类声明所确定的。根据相应的查找规则
对于A中的m_data,在A的getData()中绑定this+0取得,对于B中的m_data,在B的getData()中绑定this+4取的。
虚函数中也是一样的,所以最关键的是看调用的是谁的函数,如果调用父类的函数,则是父类的变量,子类的函数,,则是子类的变量。
cvison 2008-12-22
  • 打赏
  • 举报
回复
在实际开发中有哪些地方会用到这种奇怪的用法呢!反正我还没怎么遇到!
也许我太现实了,现在学的都是解决工作中要用到的东西!
也不是说研究这东西就没用,但是要明白当前最重要的是什么...你自己都说了,你是刚开始学习C++,所以还是先学常用的东西吧!

在下的一点愚见,未必对哈...
**********************************
哈哈,仁兄说的太对了。实际中一般不会遇到这么的事情的。

对咱中国人来讲,最常用的就是考试的时候才考试这么变态的东西,也就是面试啊。

最近面试中老是被各位牛人bs c++,一气之下,开始学习C++.上面的问题也是某个公司的面试题。
luojc714 2008-12-22
  • 打赏
  • 举报
回复
在实际开发中有哪些地方会用到这种奇怪的用法呢!反正我还没怎么遇到!
也许我太现实了,现在学的都是解决工作中要用到的东西!
也不是说研究这东西就没用,但是要明白当前最重要的是什么...你自己都说了,你是刚开始学习C++,所以还是先学常用的东西吧!

在下的一点愚见,未必对哈...
lann64 2008-12-22
  • 打赏
  • 举报
回复
作用域查找都是从内向外查找的。类里面是当前类,然后父类。
xiaoyisnail 2008-12-22
  • 打赏
  • 举报
回复
c++编程思想14.5节
blueness21 2008-12-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 cvison 的回复:]
呵呵,21天学会c++ //这个我看过一点,当年这书还没写完貌似,而且那会我以娱乐心态看的C++,书写的不错

c++ primer实在是看不懂

虚函数各个书上都有讲解的,我也明白函数的继承、覆盖、隐藏等,这个没问题。

我不懂的是 变量的访问域隐藏规则 两个一样,函数会访问那个啊。 //看看多态的特性
多谢。我去看看变量的访问域隐 藏规则 和c++ primer寻找答案去
[/Quote]
lann64 2008-12-22
  • 打赏
  • 举报
回复
如果B中没有定义getData,那么 b.getData返回的是b.A::m_data; b.A::getData返回的是b.A::m_data,b怎么调用自己的m_data啊。
--------------
没法调用,你的定义B或者其派生类的函数来访问B::m_data,基类A的函数是不能访问B的变量的。
blueness21 2008-12-22
  • 打赏
  • 举报
回复
我也发现,我不该说话的。。。丢人。。。
cvison 2008-12-22
  • 打赏
  • 举报
回复
呵呵,21天学会c++

c++ primer实在是看不懂

虚函数各个书上都有讲解的,我也明白函数的继承、覆盖、隐藏等,这个没问题。

我不懂的是 变量的访问域隐藏规则 两个一样,函数会访问那个啊。

多谢。我去看看变量的访问域隐 藏规则 和c++ primer寻找答案去
nullah 2008-12-22
  • 打赏
  • 举报
回复
up~~~~
大牛来了 就不用我们了
blueness21 2008-12-22
  • 打赏
  • 举报
回复
你看的哪本书?
书上对这些肯定都讲的。
基类的成员函数有virtual的话,那个函数就叫虚函数,那个类就叫做虚基类。
派生类对象对虚函数的调用,涉及到多态的应用。
如果你没看过这方面的书的话,三言两语也说不清楚。
建议你买些比较好评的书来看。
例如 《C++ Primer Plus》
我在看《C++ Primer 4th》

加载更多回复(3)

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧