【发布时间】:2015-03-27 10:16:43
【问题描述】:
与this question相关;下面的代码试图隐藏每个特定组件实现的公共构造函数,同时在每个组件上提供一个通用的create 函数(它的实现总是做同样的事情:通过管道与服务器通信)。
通过使用多重继承,我试图向需要访问组件字段的组件添加功能。由于我只希望每个组件中有一个 g_component 实例,因此我使用虚拟继承。
g_component 类如下所示:
class g_component {
protected:
uint32_t id;
g_component(uint32_t id) :
id(id) {
}
template<typename T>
class g_concrete: virtual T {
public:
g_concrete(uint32_t id) :
T(id) { // <----------- this fails compilation
}
};
template<typename COMPONENT_TYPE, uint32_t COMPONENT_CONSTANT>
static COMPONENT_TYPE* createComponent() {
// write request: using the COMPONENT_CONSTANT
// read response: component_id is read from the response
if (response_successful) {
return new g_concrete<COMPONENT_TYPE>(component_id);
}
return 0;
}
};
然后是可以有标题的g_titled_component:
class g_titled_component: virtual public g_component {
public:
g_titled_component(uint32_t id) :
g_component(id) {
}
virtual ~g_titled_component() {
}
virtual void setTitle(std::string title) {
// this implementation must have access to g_component::id
}
};
最后,g_button 及其实现如下所示:
class g_button: virtual public g_component, virtual public g_titled_component {
protected:
g_button(uint32_t id) :
g_component(id), g_titled_component(id) {
}
public:
static g_button* create();
};
g_button* g_button::create() {
return createComponent<g_button, G_UI_COMPONENT_BUTTON>();
}
这样应该没问题,因为通过虚继承,g_component的构造函数只会被调用一次。问题是,在g_concrete的构造函数中调用父构造函数时编译失败:
In file included from src/ui/button.hpp:13:0,
from src/ui/button.cpp:12:
src/ui/component.hpp: In instantiation of 'static COMPONENT_TYPE* g_component::createComponent() [with COMPONENT_TYPE = g_button; unsigned int COMPONENT_CONSTANT = 0u]':
src/ui/button.cpp:18:58: required from here
src/ui/component.hpp:71:54: error: 'g_button' is an inaccessible base of 'g_component::g_concrete<g_button>'
return new g_concrete<COMPONENT_TYPE>(component_id);
^
src/ui/component.hpp: In instantiation of 'g_component::g_concrete<T>::g_concrete(uint32_t) [with T = g_button; uint32_t = unsigned int]':
src/ui/component.hpp:71:54: required from 'static COMPONENT_TYPE* g_component::createComponent() [with COMPONENT_TYPE = g_button; unsigned int COMPONENT_CONSTANT = 0u]'
src/ui/button.cpp:18:58: required from here
src/ui/component.hpp:38:9: error: no matching function for call to 'g_component::g_component()'
T(id) {
^
src/ui/component.hpp:38:9: note: candidates are:
src/ui/component.hpp:27:2: note: g_component::g_component(uint32_t)
g_component(uint32_t id) :
^
src/ui/component.hpp:27:2: note: candidate expects 1 argument, 0 provided
src/ui/component.hpp:23:7: note: constexpr g_component::g_component(const g_component&)
class g_component {
^
src/ui/component.hpp:23:7: note: candidate expects 1 argument, 0 provided
src/ui/component.hpp:23:7: note: constexpr g_component::g_component(g_component&&)
src/ui/component.hpp:23:7: note: candidate expects 1 argument, 0 provided
src/ui/component.hpp:38:9: error: no matching function for call to 'g_titled_component::g_titled_component()'
T(id) {
^
src/ui/component.hpp:38:9: note: candidates are:
In file included from src/ui/button.hpp:14:0,
from src/ui/button.cpp:12:
src/ui/titled_component.hpp:30:2: note: g_titled_component::g_titled_component(uint32_t)
g_titled_component(uint32_t id) :
^
src/ui/titled_component.hpp:30:2: note: candidate expects 1 argument, 0 provided
src/ui/titled_component.hpp:22:7: note: g_titled_component::g_titled_component(const g_titled_component&)
class g_titled_component: virtual public g_component {
^
src/ui/titled_component.hpp:22:7: note: candidate expects 1 argument, 0 provided
为什么这不起作用? g_concrete的虚继承不应该调用g_button的ctor,导致g_component的ctor被调用吗?
【问题讨论】:
标签: c++ templates inheritance virtual-inheritance