我试图通过使用接口(interface)来创建一个非常模块化的程序。来自C#背景,我将接口(interface)用作变量类型,因此可以使用多态性,从而允许自己(他人)将继承自该接口(interface)的许多不同对象传递到函数/变量中。
但是,在C++中尝试执行此操作时,出现很多奇怪的错误。我在这里做错了什么?

我希望能够有接口(interface)类型的变量。但是,以下产生编译错误。我认为编译器认为我的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

编译错误:

谢谢,
-弗朗西斯科

最佳答案

ILogger * errorLogger = ErrorLogger();errorLogger是一个指针,您需要使用new operator对其进行初始化。

定义指向已删除类的基本指针的正确方法是:

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

更好地在现代C++中使用智能指针:
#include <memory>
std::unique_ptr<automation::ILogger> errorLoggerPtr(new automation::ErrorLogger());

另外,您还需要在IError.h中包括ILogger.h
#include "IError.h"

其他建议:

1使用文件的 fstream istead
2使用 std::wstring 代替 wchar_t *
cpp文件中有2个,请勿调用
using namespace automation;

而是使用 namespace 包装函数定义,就像您在头文件中所做的那样:
namespace automation
{
    ErrorLogger::ErrorLogger(const std::wstring& file, std::ofstream& stream)
    {
    }
}

关键是不要将C++代码与C代码,字符串之类的C++类,fstream提供RAII混合使用,它更安全,更容易使用。

关于c++ - C++接口(interface)声明/定义和用法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17625252/

10-09 08:12