2013-07-12 110 views
0

我想通過使用接口創建一個非常模塊化的程序。來自C#的背景,我會使用接口作爲變量類型,所以我可以使用多態,允許我/他人將從此接口繼承的許多不同對象傳遞給函數/變量。 但是,當我嘗試在C++中執行此操作時,出現了許多奇怪的錯誤。我在這裏做錯了什麼?C++接口聲明/定義和用法

我希望能夠有接口類型的變量。但是,以下產生編譯錯誤。我認爲編譯器認爲我的ErrorLogger類是抽象的,因爲它從一個抽象類繼承而來。

ILogger * errorLogger = ErrorLogger(); 

error C2440: 'initializing' : cannot convert from 'automation::ErrorLogger' to 'automation::ILogger *' 

如果我要對這個錯誤的方式,甚至設計的角度來看,我正在學習,並樂意聽取任何和所有的建議。

ILogger.h:

#ifndef _ILOGGER_H_ 
#define _ILOGGER_H_ 

namespace automation 
{ 
    class ILogger 
    { 
    public: 
     virtual void Log(const IError &error) = 0; 
    }; 
} 
#endif 

ErrorLogger.h:

#ifndef _ERRORLOGGER_H_ 
#define _ERRORLOGGER_H_ 
#include "ILogger.h" 
#include "IError.h" 

/* Writes unhandled errors to a memory-mapped file. 
* 
**/ 

namespace automation 
{ 
    class ErrorLogger : public ILogger 
    { 
    public: 
     ErrorLogger(const wchar_t * file = nullptr, const FILE * stream = nullptr); 
     ~ErrorLogger(void); 
     void Log(const IError &error); 
    }; 
} 
#endif 

ErrorLogger.cpp:

#include "stdafx.h" 
#include "ErrorLogger.h" 
#include "IError.h" 

using namespace automation; 

ErrorLogger::ErrorLogger(const wchar_t * file, const FILE * stream) 
{ 

} 

void ErrorLogger::Log(const IError &error) 
{ 
    wprintf_s(L"ILogger->ErrorLogger.Log()"); 
} 

ErrorLogger::~ErrorLogger(void) 
{ 
} 

IError.h:

#ifndef _IERROR_H_ 
#define _IERROR_H_ 

namespace automation 
{ 
    class IError 
    { 
    public: 
     virtual const wchar_t *GetErrorMessage() = 0; 
     virtual const int &GetLineNumber() = 0; 
    }; 
} 
#endif 

個編譯錯誤:

enter image description here

感謝, -Francisco

+0

在C++中,多態性需要使用指針(可能是智能指針)或引用。 –

+2

編譯錯誤不可小覷。你可以把它們放在純文本而不是照片上嗎? – PherricOxide

+2

請發佈實際的代碼,而不是圖像。 –

回答

2

ILogger * errorLogger = ErrorLogger(); errorLogger是一個指針,你需要用new operator來初始化它。

定義基指針的正確方法,它指向derieved類:

automation::ILogger * errorLogger = new automation::ErrorLogger(); 
//         ^^^^ 

更好地利用智能指針在現代C++:

#include <memory> 
std::unique_ptr<automation::ILogger> errorLoggerPtr(new automation::ErrorLogger()); 

你也需要包括IError.hILogger.h

#include "IError.h" 

其他建議:

1使用fstream的isntead的FILE 2使用的std :: wstring的的代替爲wchar_t * 2 CPP文件,不」來電

using namespace automation; 

,而不是包裹函數的定義與命名空間,就像你在頭文件中做的那樣:

namespace automation 
{ 
    ErrorLogger::ErrorLogger(const std::wstring& file, std::ofstream& stream) 
    { 
    } 
} 

關鍵是不要將C++代碼與C代碼混合使用,C++類似字符串,fstream提供RAII,它更安全,更易於使用。

+0

謝謝@billz。雖然這確實起作用,那麼這是否意味着我無法初始化指向堆棧中的ErrorLogger的ILogger指針?因爲新的關鍵字在堆中分配它不是嗎? –

+0

你是否在ILogger.h中#include「IError.h」? – billz

+0

是的,我解決了這個問題:) –

0

您需要#include "IError.h"ILogger.h頭文件。

+0

啊,那是我的愚蠢。我的另一個問題呢?我認爲編譯器認爲我的ErrorLogger類是抽象的,因爲它繼承自一個抽象類或其他類。 ILogger logger = ErrorLogger() ; 如果我正在以這種錯誤的方式去做,即使在設計方面,我也在學習,並樂意聽取任何和所有的建議。「 –