2009-10-21 75 views
2

LessonInterfaceC++接口在STL ::列表

class ILesson 
{ 
    public: 
     virtual void PrintLessonName() = 0; 
     virtual ~ILesson() {} 
}; 

STL容器

typedef list<ILesson> TLessonList; 

调用代码

for (TLessonList::const_iterator i = lessons.begin(); i != lessons.end(); i++) 
    { 
     i->PrintLessonName(); 
    } 

错误:

Description Resource Path Location Type passing ‘const ILesson’ as ‘this’ argument of ‘virtual void ILesson::PrintLessonName()’ discards qualifiers

回答

7

你不能“放”具有纯虚函数的类的对象(因为你不能实例化它)。也许你的意思是:

// store a pointer which points to a child actually. 
typedef list<ILesson*> TLessonList; 

OK,正如其他人指出的那样,你必须做出一个PrintLessonName成员const功能。我想补充一点,这里还有一个小陷阱。 PrintLessonName必须在basederived两个类const,否则会具有相同的签名:

class ILesson 
{ 
public: 
    virtual void PrintLessonName() const = 0; 
    virtual ~ILesson() {} 
}; 


class SomeLesson : public ILesson 
{ 
public: 
    // const is mandatory in the child 
    virtual void PrintLessonName() const 
    { 
     // 
    } 
    virtual ~SomeLesson() {} 
}; 

说实话,我找到了重新设计打印功能Jerry Coffin's答案有帮助。

+0

虽然这是真的,但错误信息插孔已粘贴不是由于此错误。 – sbi 2009-10-21 15:18:57

+0

尝试和错误是: 说明\t \t资源路径\t \t位置类型 请求构件 'PrintLessonName' 在 '* i.std :: _ List_const_iterator <_Tp> ::操作符 - > [与_TP = ILesson *]()',这是非类类型'ILesson * const' – 2009-10-21 15:19:08

+0

我没有观察到const问题,我的眼睛第一次落在'typedef list TLessonList;'。无论如何,他还必须解决这个问题。 – AraK 2009-10-21 15:21:02

1

您可以通过对const对象的引用调用const对象的非const方法。

不管怎么说:

我敢肯定,100%,你需要有一个指针列表:为了利用多态性的优势

typedef list<ILesson*> TLessonList; 

由于ILesson是一个抽象类,拥有一个ILesson值列表是不可能的。

不要忘记删除指针列表中的对象,以避免内存泄漏。

3

的使用iterator代替const_iterator或使PrintLessonName() const函数:

virtual void PrintLessonName() const = 0 
+0

呃。那么用“const”来代替函数呢?这不像我们所期望的打印来改变打印物体。 – sbi 2009-10-21 15:19:33

+2

阅读我的答案“或使功能CONST” – 2009-10-21 15:23:29

+0

啊,我的大脑像Arak的这里工作。阅读删除“常量”的建议,并用于降低投票。抱歉。我将删除我的倒票(但只要你建议删除'const',就不会投票)。 – sbi 2009-10-21 15:34:12

10

PrintLessonName必须声明为const能够在常量ILessons被调用。否则,编译器会假定它可能会修改ILesson并阻止该调用。

virtual void PrintLessonName() const = 0; 
3

您必须制作PrinLessonName常量。

virtual void PrintLessonName() const = 0; 

当然,或者不使用const_iterator。

3

你想要一个指向ILesson的指针列表。

IMO,你也将会是相当富裕添加类似:

std::ostream &operator<<(std::ostream &os, ILesson const *il) { 
    il->PrintLessonName(os); 
    return os; 
} 

然后,而不是你上面写的循环,你可以使用类似:

std::copy(lessons.begin(), lessons.end(), 
      std::ostream_iterator<ILesson *>(std::cout)); 

正如您所看到的,我在此过程中添加了一个其他次要点缀 - PrintLessonName将流作为其参数,而不是始终打印到相同的位置。当然,如果你不使用流,你可能不希望这样......

编辑:当然是你想PrintLessonPlan常量也是正确的其他意见...

+0

+1我认为这应该如何在* C++ * :)中完成 – AraK 2009-10-21 15:33:18

0

人是正确的关于const的缺乏。 我希望使用for_each算法,这会阻止每个条目调用lessons.end()。

#include <algorithm> //for for_each() 

然后用这个:

std::for_each( lessons.begin(), lessons.end(), std::mem_fun(&ILesson::PrintLessonName)) 
1

像这样的版本:)

for (TLessonList::const_iterator i=lessons.begin(), m=lessons.end(); i!=m; ++i) 
    { 
     i->PrintLessonName(); 
    } 

lessons.end(被调用一次,也注意到++我,而不是我++,它速度更快(增量后运算符涉及创建临时对象,而预增量不包含)。