// ---------------------------------------------------------------------------------
Объявим интерфейс:
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,...); может быть в том числе где-то в библиотечных модулях. Она не знает, куда будет выводить и будет ли вообще. Всё определится конкретным проектом.
-
- Как-то неубедительно. Ничто не мешает в данном случае вместо указателей на объекты передавать ссылки на них, просто кое-где внутри вместо -> появится точка и не нужно будет проверять указатель на NULL, ссылок "в никуда" не бывает. Но указатели в плюсах всё-таки нужны. Ведь программа, которая ничего не выводит наружу это никому не нужный сферический конь в вакууме. А без указателей не получится наладить взаимодействие с нижним уровнем, который использует апи в с-стиле и ЫЫyкпy(35 знак., 06.08.2022 05:57)
- Спасибо! Осмыслить надо. Мастер Klen, что скажете? - Evgeny_CD(06.08.2022 03:32)
- Однажды возник вопрос - как обрабатывать прерывания в классе.
Конечно же так: Tyмблep(2578 знак., 06.08.2022 00:27)
- Предположим я сделал объект-comm port. Tyмблep(300 знак., 06.08.2022 00:42)