2009-10-21 78 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(被調用一次,也注意到++我,而不是我++,它速度更快(增量後運算符涉及創建臨時對象,而預增量不包含)。