Visual Studio 2008 中的嵌套继承问题
我目前正在开发基于小部件的图形用户界面。它的结构是一棵树,以 Widgets 作为叶子,以 Containers 作为树的节点。此结构的(可解决的)问题是 Widget 类获取对其父级 Container 的引用。然而,这使得 Container 类无法访问 Widget 类的受保护成员(这里“draw”成员造成了麻烦)。
这是导致问题的代码的核心。当然这可以通过公开成员来解决。然而,这不是我想要的风格。
ClassesTest.h:
class Container;
class Widget {
public:
Widget(Container *parent);
virtual ~Widget();
protected:
Container *parent;
virtual void draw();
};
class Container : public Widget {
public:
Container(Container *parent);
virtual ~Container();
protected:
std::list<Widget *> childs;
private:
friend Widget::Widget(Container *);
friend Widget::~Widget();
virtual void draw();
void addChild(Widget *child);
void removeChild(Widget *child);
};
ClassesTest.cpp
#include "stdafx.h"
#include "ClassesTest.h"
Widget::Widget(Container *parent) {
this->parent = parent;
parent->addChild(this);
}
Widget::~Widget() {
parent->removeChild(this);
}
void Widget::draw() {
//Draw the leaf
}
Container::Container(Container *parent) : Widget(parent) {}
Container::~Container() {}
void Container::draw() {
//Draw all the childs
for (std::list<Widget *>::iterator i = childs.begin(); i != childs.end(); i++) {
(*i)->draw();
}
}
void Container::addChild(Widget *child) {
childs.push_back(child);
}
void Container::removeChild(Widget *child) {
childs.remove(child);
}
int main(int argc, char* argv[])
{
//Do something useful!
return 0;
}
这是当我尝试编译代码时 Visual Studio 2008 给我的输出:
1>------ Build started: Project: ClassesTest, Configuration: Debug Win32 ------
1>Compiling...
1>ClassesTest.cpp
1>e:\visual studio 2008\projects\classestest\classestest\classestest.cpp(26) : error C2248: 'Widget::draw' : cannot access protected member declared in class 'Widget'
1> e:\visual studio 2008\projects\classestest\classestest\classestest.h(14) : see declaration of 'Widget::draw'
1> e:\visual studio 2008\projects\classestest\classestest\classestest.h(6) : see declaration of 'Widget'
1>Build log was saved at "file://e:\Visual Studio 2008\Projects\ClassesTest\ClassesTest\Debug\BuildLog.htm"
1>ClassesTest - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
任何建议将不胜感激!
菲利普
I am currently working on a widget-based graphical user interface. It is structured as a tree with Widgets as the leaves and Containers as the nodes of the tree. The (solvable) problem with this structure is that the Widget-class takes a reference to the Container that is its parent. However, this makes it impossible for the Container class to access the protected members of the Widget-class (here the "draw" member is causing trouble).
Here is the core of the code causing the problem. Of course this can be solved by making the members public. However, that is not the style that I would like.
ClassesTest.h:
class Container;
class Widget {
public:
Widget(Container *parent);
virtual ~Widget();
protected:
Container *parent;
virtual void draw();
};
class Container : public Widget {
public:
Container(Container *parent);
virtual ~Container();
protected:
std::list<Widget *> childs;
private:
friend Widget::Widget(Container *);
friend Widget::~Widget();
virtual void draw();
void addChild(Widget *child);
void removeChild(Widget *child);
};
ClassesTest.cpp
#include "stdafx.h"
#include "ClassesTest.h"
Widget::Widget(Container *parent) {
this->parent = parent;
parent->addChild(this);
}
Widget::~Widget() {
parent->removeChild(this);
}
void Widget::draw() {
//Draw the leaf
}
Container::Container(Container *parent) : Widget(parent) {}
Container::~Container() {}
void Container::draw() {
//Draw all the childs
for (std::list<Widget *>::iterator i = childs.begin(); i != childs.end(); i++) {
(*i)->draw();
}
}
void Container::addChild(Widget *child) {
childs.push_back(child);
}
void Container::removeChild(Widget *child) {
childs.remove(child);
}
int main(int argc, char* argv[])
{
//Do something useful!
return 0;
}
And this is the output Visual Studio 2008 gives me when I am trying to compile my code:
1>------ Build started: Project: ClassesTest, Configuration: Debug Win32 ------
1>Compiling...
1>ClassesTest.cpp
1>e:\visual studio 2008\projects\classestest\classestest\classestest.cpp(26) : error C2248: 'Widget::draw' : cannot access protected member declared in class 'Widget'
1> e:\visual studio 2008\projects\classestest\classestest\classestest.h(14) : see declaration of 'Widget::draw'
1> e:\visual studio 2008\projects\classestest\classestest\classestest.h(6) : see declaration of 'Widget'
1>Build log was saved at "file://e:\Visual Studio 2008\Projects\ClassesTest\ClassesTest\Debug\BuildLog.htm"
1>ClassesTest - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Any suggestions would be appreciated!
Filip
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于您的具体问题,您的代码本质上与此相同:
问题是,尽管
Derived
继承自Base
,但它仍然无法访问Base
的受保护成员。访问权限在这里的工作方式如下:Base
是,Derived
就不能访问Base
的受保护内容另一个例子。Derived
可以在其自己的实例中访问Base
受保护的内容。Derived
可以访问另一个Derived
的私有内容。解决问题的最快方法可能是让
Container::draw()
成为Widget
的朋友。Your code is essentially equal to this, with regard to your specific problem:
The problem is that although
Derived
inherits fromBase
, it still doesn't have access toBase
's protected members. The way access rights works here is as follows:Derived
can not accessBase
's protected stuff ifBase
is a different instance.Derived
can accessBase
's protected stuff in it's own instance.Derived
can access anotherDerived
's private stuff.The quickest way to solve your problem would probably make
Container::draw()
a friend ofWidget
.