Сообщение Re: как лучше сделать от 26.02.2020 9:56
Изменено 26.02.2020 10:21 Erop
Re: как лучше сделать
Здравствуйте, sergey2b, Вы писали:
S>3) у класса есть метод setup но в нем передаеться только путь к файлу который этот класс будет обрабатывать
S>можно через эту строку передавать опции и внутри парсить
S>выглядит убого но все изменения затронут только один нужный мне класс
S>как лучше сделать добавление новых методов getOption setOption
1) Если во время существования объекта не надо иметь доступ к доп. параметрам, то мне тоже нравится решение от
rg45
2) Если же всё-таки нужны именно методы getOption setOption (например, есть какие-то версии доп. параметров для некоторых объектов и мы пробуем применять то одни, то другие), то можно пойти по python/smalltalk-style пути и передавать либо имя/ID доп. опции в методы getOption setOption БАЗЫ
либо std::map<std::string, int>
Но неудобно то, что динамики многовато для С++ и то, что если в разных классах понадобятся разные типы, то будет неудобно.
Хотя разные типы обеспечить более или менее можно
3) Завести структуру/класс ExtraOptions с виртуальным деструктором. Для тех классов, кому надо, выводить из неё расширенные версии.
В метод setOption передавать ссылку на такую структуру, а в методе класса dyn_cast'ом кастить вниз и получать доступ туда, куда нужно
А из getOption сразу возвращать выведенную структуру.
Вот пруф оф концепт:
https://www.ideone.com/e7bQ52
выдаёт
[/cut]
S>3) у класса есть метод setup но в нем передаеться только путь к файлу который этот класс будет обрабатывать
S>можно через эту строку передавать опции и внутри парсить
S>выглядит убого но все изменения затронут только один нужный мне класс
S>как лучше сделать добавление новых методов getOption setOption
1) Если во время существования объекта не надо иметь доступ к доп. параметрам, то мне тоже нравится решение от
rg45
2) Если же всё-таки нужны именно методы getOption setOption (например, есть какие-то версии доп. параметров для некоторых объектов и мы пробуем применять то одни, то другие), то можно пойти по python/smalltalk-style пути и передавать либо имя/ID доп. опции в методы getOption setOption БАЗЫ
либо std::map<std::string, int>
Но неудобно то, что динамики многовато для С++ и то, что если в разных классах понадобятся разные типы, то будет неудобно.
Хотя разные типы обеспечить более или менее можно
3) Завести структуру/класс ExtraOptions с виртуальным деструктором. Для тех классов, кому надо, выводить из неё расширенные версии.
В метод setOption передавать ссылку на такую структуру, а в методе класса dyn_cast'ом кастить вниз и получать доступ туда, куда нужно
А из getOption сразу возвращать выведенную структуру.
Вот пруф оф концепт:
https://www.ideone.com/e7bQ52
#include <iostream>
#include <string>
#include <map>
#include <assert.h>
struct IObj {
//------ Подход 3 ----------------------------------------------
struct ExtraOptionsBase {
virtual ~ExtraOptionsBase() {}
};
virtual void SetEO( ExtraOptionsBase& ) = 0; // Можно сделдать дефолтную пустую реализацию
virtual ExtraOptionsBase& GetEO() = 0;
//------ Подход 2 ----------------------------------------------
virtual bool SetOption( const std::string& name, const int& value ) { return false; }
virtual bool TryGetOption( const std::string& name, int& value ) { return false; }
virtual bool SetOption( const std::string& name, const std::string& value ) { return false; }
virtual bool TryGetOption( const std::string& name, std::string& value ) { return false; }
template<typename T> T GetOption( const std::string& name ) {
T res = T();
bool is_ok = this->TryGetOption( name, res );
assert( is_ok );
return res;
}
};
template<typename T>
struct CObj : public IObj {
//------ Подход 3 ----------------------------------------------
struct ExtraOptions : public IObj::ExtraOptionsBase {
T Param1;
T Param2;
T* getField( const std::string& name ) {
if( name == "Param1" )
return &this->Param1;
if( name == "Param2" )
return &this->Param2;
return 0;
}
} Data;
virtual ExtraOptions& GetEO() { return this->Data; }
virtual void SetEO( ExtraOptions& ed ) { this->Data = ed; }
virtual void SetEO( ExtraOptionsBase& ed ) { this->Data = dynamic_cast<ExtraOptions&>(ed); }
//------ Подход 2 ----------------------------------------------
virtual bool SetOption( const std::string& name, const T& value ) {
T* field = this->Data.getField( name );
if( field ) {
*field = value;
return true;
}
return false;
}
virtual bool TryGetOption( const std::string& name, T& value ) {
T* field = this->Data.getField( name );
if( field ) {
value = *field;
return true;
}
return false;
}
};
using namespace std;
int main() {
std::map<std::string, int> pi = {
{ "Param1", 5 },
{ "Param2", 10 },
};
CObj<int> oi1, oi2;
for( auto i = pi.begin(); i != pi.end(); ++i )
oi1.SetOption( i->first, i->second );
oi2.SetEO( oi1.GetEO() );
std::cout << oi2.GetEO().Param1 << " " << oi2.GetOption<int>( "Param2" ) << std::endl;
std::map<std::string, std::string> ps = {
{ "Param1", "Hello" },
{ "Param2", "world!" },
};
CObj<std::string> os1;
for( auto i = ps.begin(); i != ps.end(); ++i )
os1.SetOption( i->first, i->second );
std::cout << os1.GetEO().Param1 << " " << os1.GetOption<std::string>( "Param2" ) << std::endl;
// your code goes here
return 0;
}
выдаёт
5 10
Hello world!
[/cut]
Re: как лучше сделать
Здравствуйте, sergey2b, Вы писали:
S>3) у класса есть метод setup но в нем передаеться только путь к файлу который этот класс будет обрабатывать
S>можно через эту строку передавать опции и внутри парсить
S>выглядит убого но все изменения затронут только один нужный мне класс
S>как лучше сделать добавление новых методов getOption setOption
1) Если во время существования объекта не надо иметь доступ к доп. параметрам, то мне тоже нравится решение от
rg45
2) Если же всё-таки нужны именно методы getOption setOption (например, есть какие-то версии доп. параметров для некоторых объектов и мы пробуем применять то одни, то другие), то можно пойти по python/smalltalk-style пути и передавать либо имя/ID доп. опции в методы getOption setOption БАЗЫ
либо std::map<std::string, int>
Но неудобно то, что динамики многовато для С++ и то, что если в разных классах понадобятся разные типы, то будет неудобно.
Хотя разные типы обеспечить более или менее можно
3) Завести структуру/класс ExtraOptions с виртуальным деструктором. Для тех классов, кому надо, выводить из неё расширенные версии.
В метод setOption передавать ссылку на такую структуру, а в методе класса dyn_cast'ом кастить вниз и получать доступ туда, куда нужно
А из getOption сразу возвращать выведенную структуру.
https://www.ideone.com/e7bQ52
S>3) у класса есть метод setup но в нем передаеться только путь к файлу который этот класс будет обрабатывать
S>можно через эту строку передавать опции и внутри парсить
S>выглядит убого но все изменения затронут только один нужный мне класс
S>как лучше сделать добавление новых методов getOption setOption
1) Если во время существования объекта не надо иметь доступ к доп. параметрам, то мне тоже нравится решение от
rg45
2) Если же всё-таки нужны именно методы getOption setOption (например, есть какие-то версии доп. параметров для некоторых объектов и мы пробуем применять то одни, то другие), то можно пойти по python/smalltalk-style пути и передавать либо имя/ID доп. опции в методы getOption setOption БАЗЫ
либо std::map<std::string, int>
Но неудобно то, что динамики многовато для С++ и то, что если в разных классах понадобятся разные типы, то будет неудобно.
Хотя разные типы обеспечить более или менее можно
3) Завести структуру/класс ExtraOptions с виртуальным деструктором. Для тех классов, кому надо, выводить из неё расширенные версии.
В метод setOption передавать ссылку на такую структуру, а в методе класса dyn_cast'ом кастить вниз и получать доступ туда, куда нужно
А из getOption сразу возвращать выведенную структуру.
https://www.ideone.com/e7bQ52
"Вот пруф оф концепт: " | |
выдаёт
| |