ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
28 марта
1229681 Топик полностью
Tyмблep (06.08.2022 00:22, просмотров: 208) ответил Tyмблep на Да, сейчас состряпаю. Минуточку.
Предположим, решаем важный вопрос - делаем логгер. 

// ---------------------------------------------------------------------------------

Объявим интерфейс:

class I_Type

{

public:

private:

protected:

public:

virtual bool WINAPI TypeStr (const TCHAR* pStr)=0;

};


// ---------------------------------------------------------------------------------

В каком-то модуле текст а-ля С: // --------------------------------------------------------------------------------- // Объявим указатель на интерфейс: I_Type* pTypeObj=NULL; // --------------------------------------------------------------------------------- // процедура установки указателя: void WINAPI Set_I_Type(I_Type* p) { pTypeObj = p; } // --------------------------------------------------------------------------------- Половина работы сделана. Напишем ф-ию вывода в интерфейс: // --------------------------------------------------------------------------------- void WINAPI AppTypeMessageF (const TCHAR* pFormat,...) { va_list ap; //Указатель на список параметров va_start(ap,pFormat); //Настроились на список параметров TCHAR sss[8192]; _vsntprintf_s(sss,ARRAYSIZE(sss),_TRUNCATE,pFormat,ap); if(pTypeObj) pTypeObj->TypeStr(sss); va_end(ap); //Завершаем работу с макрокомандами } // --------------------------------------------------------------------------------- Всё. Теперь нужно писать реализации интерфейса. Если реализаций не будет, паталогии не будет. Но и вывода не будет. Объект вывода в консоль: //--------------------------------------------------------------------------- // file ConOut.h 2020.11.12 //--------------------------------------------------------------------------- #ifndef __ConOut_H__ #define __ConOut_H__ //--------------------------------------------------------------------------- #include "I_Type.h" //--------------------------------------------------------------------------- class ConOut : virtual public I_Type { public: private: protected: public: WINAPI ConOut (void); virtual WINAPI ~ConOut (void); virtual bool WINAPI TypeStr (const TCHAR* pStr); WINAPI operator I_Type* (); }; #endif //--------------------------------------------------------------------------- // -------------------------------------------------------------------------- // FILE ConOut.cpp 2020.11.12 // -------------------------------------------------------------------------- #include "stdafx.h" #include "ConOut.h" //--------------------------------------------------------------------------- WINAPI ConOut::ConOut () { } // -------------------------------------------------------------------------- WINAPI ConOut::~ConOut () { } //--------------------------------------------------------------------------- bool WINAPI ConOut::TypeStr (const TCHAR* pStr) { if(!pStr) return false; _tprintf(pStr); return true; } //--------------------------------------------------------------------------- WINAPI ConOut::operator I_Type* () { return this; } //--------------------------------------------------------------------------- Объект вывода в DbgView: //--------------------------------------------------------------------------- // file ODS.h 2019.05.02 //--------------------------------------------------------------------------- #ifndef __ODS_H__2019_05_02_ #define __ODS_H__2019_05_02_ //--------------------------------------------------------------------------- #include "I_Type.h" //--------------------------------------------------------------------------- class ODS : virtual public I_Type { public: static const TCHAR* pPreffics; private: protected: public: WINAPI ODS (void); virtual WINAPI ~ODS (void); virtual bool WINAPI TypeStr (const TCHAR* pStr); void WINAPI SetPreffics (const TCHAR* pPreff); WINAPI operator I_Type* (); }; //--------------------------------------------------------------------------- #endif // -------------------------------------------------------------------------- // FILE ODS.cpp 2019.05.02 // -------------------------------------------------------------------------- #include "stdafx.h" #include "ODS.h" #include "mstr.h" //#include "TypeDebugString.h" //--------------------------------------------------------------------------- const TCHAR* ODS::pPreffics = NULL; //--------------------------------------------------------------------------- WINAPI ODS::ODS () { } // -------------------------------------------------------------------------- WINAPI ODS::~ODS () { } //--------------------------------------------------------------------------- void WINAPI ODS::SetPreffics (const TCHAR* pPreff) { ... } //--------------------------------------------------------------------------- bool WINAPI ODS::TypeStr (const TCHAR* pStr) { if(!pStr) return false; OutputDebugString(str); return true; } //--------------------------------------------------------------------------- WINAPI ODS::operator I_Type* () { return this; } //--------------------------------------------------------------------------- Несколько сложнее, но похоже делается вывод на сервер, в файл и куда угодно. На мэйл или в EEPROM, подключенный к RS232. Как апофеоз идеи, делается объект/реализация ничего сам не делающий, а являющийся контейнером указателей на интерфейсы. Это значит, можно производить вывод одновременно в разный набор "дивайсов" в любой последовательности для конкретного проекта. Используем: void main (void) { ConOut con; // вывод в консоль ODS ods; // вывод в DbgView DBGVB dbgvb; // вывод в UDP-сервер dbgvb.install (PORT, IP); LogTyper log; // вывод в файл log.SetLogName(nameFile); MTyper mtyper; // контейнер интерфейсов // этот набор зависит от проекта и потребностей mtyper.Add(&con); mtyper.Add(&ods); mtyper.Add(&dbgvb); mtyper.Add(&log); Set_I_Type(&mtyper); // ... } Заметим, что процедура AppTypeMessageF (const TCHAR* pFormat,...); может быть в том числе где-то в библиотечных модулях. Она не знает, куда будет выводить и будет ли вообще. Всё определится конкретным проектом.