在C+中使用抽象类型时出错+;模板 在C++中实现一个入侵容器时,我遇到了一些奇怪的问题。 给出以下简化代码: struct IFace { virtual int foo() const = 0; }; struct Impl : public IFace { int foo() const { return 111; } }; template <typename T> struct IntrusiveHook { T item; IntrusiveHook<T>* next; }; template <typename T> struct IntrusiveList { IntrusiveList() : head(0), tail(0) {} template <typename U> void add(IntrusiveHook<U>& addItem) { if (0 == head) { head = reinterpret_cast<IntrusiveHook<T>*>(&addItem); tail = head; } else { tail->next = reinterpret_cast<IntrusiveHook<T>*>(&addItem); tail = tail->next; } } IntrusiveHook<T>* head; IntrusiveHook<T>* tail; }; void testList() { IntrusiveHook<Impl> impl; IntrusiveList<IFace> list; list.add(impl); // list.head->item.foo(); }
当在在C+中使用抽象类型时出错+;模板 在C++中实现一个入侵容器时,我遇到了一些奇怪的问题。 给出以下简化代码: struct IFace { virtual int foo() const = 0; }; struct Impl : public IFace { int foo() const { return 111; } }; template <typename T> struct IntrusiveHook { T item; IntrusiveHook<T>* next; }; template <typename T> struct IntrusiveList { IntrusiveList() : head(0), tail(0) {} template <typename U> void add(IntrusiveHook<U>& addItem) { if (0 == head) { head = reinterpret_cast<IntrusiveHook<T>*>(&addItem); tail = head; } else { tail->next = reinterpret_cast<IntrusiveHook<T>*>(&addItem); tail = tail->next; } } IntrusiveHook<T>* head; IntrusiveHook<T>* tail; }; void testList() { IntrusiveHook<Impl> impl; IntrusiveList<IFace> list; list.add(impl); // list.head->item.foo(); },c++,templates,C++,Templates,当在list.head->item.foo()行中进行注释时,我得到一个不同的编译错误,前一个错误被忽略了(这是一种奇怪的行为,在VC++和gcc编译器上都会发生) 有问题的调用似乎是tail->next=…,尤其是这里使用的抽象类型上的操作符-> 因此: 如何解决这个问题 在IFace中添加foo的默认实现-这不是我想要的,但它解决了问题 一种骇人的解决方案:将代码重写为tail->nextas reinterpret\u cast(tail)->next=&addItem tail=rei
list.head->item.foo()行中进行注释时,我得到一个不同的编译错误,前一个错误被忽略了(这是一种奇怪的行为,在VC++和gcc编译器上都会发生)
有问题的调用似乎是tail->next=…
,尤其是这里使用的抽象类型上的操作符->
因此:
如何解决这个问题
- 在
IFace
中添加foo
的默认实现-这不是我想要的,但它解决了问题
- 一种骇人的解决方案:将代码重写为
tail->next
as
reinterpret\u cast(tail)->next=&addItem代码>
tail=reinterpret\u cast(reinterpret\u cast(tail)->next)代码>-但它似乎不适用于VC++(2010),而是适用于gcc
- 。。。或者表演一些其他丑陋的演员
但为什么这首先是一个问题?通常,使用运算符“->”访问指针类型应该不会有问题
任何帮助都将不胜感激。谢谢
编辑:
为了方便起见,我希望IntrusiveHook已经包含该项作为实例。这也是入侵的窍门——当我做对的时候——只向项添加指针功能而不更改项本身。“新建”不是选项,因为代码应该在没有new
的嵌入式环境中运行
当然,我也希望使用带有抽象项的列表,因为使用类不知道实现类。据我所见,问题是在IntrusiveList::add
中转换到IntrusiveHook*
。您正在将addItem
转换为IntrusiveHook
<代码>入侵钩子
具有类型为IFace
的成员项
。但是IFace
是抽象的,因此不能用该类型声明变量——必须使用指针或引用
所以你必须
- 将
从类型IntrusiveHook::item
更改为T
T*
- 添加一个构造函数
IntrusiveHook(T*item):item(item){}
- 将
中的testList()
声明更改为impl
IntrusiveHook impl(新impl)
- 最后将
更改为list.head->item.foo()
list.head->item->foo()
如果您不想更改
IntrusiveList
列表,也可以使用IntrusiveList
或IntrusiveList
而不是IntrusiveList
;列表。添加(impl);或侵入列表;添加(新Impl())代码>正如错误所说:您不能实例化抽象类的对象。您的IntrusiveList不能与IFace
一起使用,因为这不是一个完整的类型,但它可以与IFace*
一起使用(因为要声明指针,您不需要知道完整的类型)。对不起,我不能使用“new”-这样会容易得多。使用动态内存时也不需要创建侵入式类型。@michael_s我不熟悉侵入式类型的概念。然而,在C++中,用抽象类型声明变量是不可能的。您必须使用指针、引用或非抽象类。
error C2259: 'IFace' : cannot instantiate abstract class
due to following members:
'int IFace::foo(void) const' : is abstract
testwas.cpp(7) : see declaration of 'IFace::foo'
testwas.cpp(25) : see reference to class template instantiation 'IntrusiveHook<T>' being compiled
with
[
T=IFace
]
testwas.cpp(41) : see reference to function template instantiation 'void IntrusiveList<T>::add<Impl>(IntrusiveHook<Impl> &)' being compiled
with
[
T=IFace
]