В настоящее время я работаю над графическим пользовательским интерфейсом на основе виджетов. Он структурирован как дерево с виджетами в качестве листьев и контейнерами в качестве узлов дерева. (Решаемая) проблема с этой структурой заключается в том, что класс Widget берет ссылку на контейнер, который является его родителем. Однако это делает невозможным для класса Container доступ к защищенным членам класса Widget (здесь член «draw» вызывает проблемы).
Вот ядро кода, вызывающего проблему. Конечно, это можно решить, сделав членов общедоступными. Однако это не тот стиль, который мне бы хотелось.
КлассыTest.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);
};
КлассыTest.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 ==========
Мы ценим любые предложения!
Филип