В конце концов, я решил, что, удалив AppBarLayout
, установив панель инструментов на прозрачный фон и добавив перевод Z, подумал, что это немного странно.
Вот код для справки:
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:translationZ="2dp"
android:fitsSystemWindows="true"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Some other layouts -->
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Выглядит хорошо мне, но для факта это descrToFuncMap
потребности, которые будут объявлены static
если Вы намереваетесь инициализировать его из статической функции Initialize()
.
Если Вы хотите удостовериться это Initialize()
назван и назван только однажды, можно использовать Шаблон "одиночка". В основном, если Вы не делаете многопоточности, которая просто означает переноситься descrToFuncMap
в его собственном классе (названный говорят FuncMap
) с частным конструктором, который звонит Initialize()
. Затем Вы добавляете a static
локальная переменная типа FuncMap
кому: Processor::Process()
- потому что переменная static
, это сохраняется и только инициализируется однажды.
Пример кода (я теперь понимаю это friend
не действительно необходимо здесь):
class Processor {
private:
typedef double (MyClass::*MemFuncGetter)();
class FuncMap {
public:
FuncMap() {
descrToFuncMap["X"]=&MyClass::GetX;
descrToFuncMap["SomethingElse"]=&MyClass::GetSomethingElse;
descrToFuncMap["RR"]=&MyClass::GetRR;
descrToFuncMap["T"]=&MyClass::GetT;
}
// Of course you could encapsulate this, but its hardly worth
// the bother since the whole class is private anyway.
map<std::string, MemFuncGetter> descrToFuncMap;
};
public:
void Process(Myclass m, string);
};
void Processor::Process(MyClass ms, const std::string& key) {
static FuncMap fm; // Only gets initialised on first call
map<std::string, Getter>::iterator found=fm.descrToFuncMap.find(key);
if(found!=fm.descrToFuncMap.end()) {
MemFuncGetter memFunc=found->second;
double dResult=(ms).*memFunc();
std::cout<<"Command="<<key<<", and result="<<result<<std::end;
}
}
Это не "истинный" Шаблон "одиночка", поскольку различные функции могли создать свои собственные, отдельные экземпляры FuncMap
, но это достаточно, для какого Вам нужно. Для "истинной" Singleton Вы объявили бы FuncMap
частный конструктор и добавляет статический метод, говорит getInstance()
, который определил one-only экземпляр как a static
переменная и возвратила ссылку на это. Processor::Process()
затем использовал бы это с
FuncMap& fm = FuncMap::getInstance();
Избегайте использования 'виртуальный' при использовании карт указателей функции. В этом контексте, с помощью 'виртуального' ключевого слова не поможет многому. Например,
descrToFuncMap["X"]=&MyClass::GetX;
будет всегда называть 'MyClass:: GetX' функционируют, даже если GetX переопределяется производным классом MyClass.
Обычно у Вас не будет большого количества функций в классе, вместо того, чтобы использовать карту, можно создать простой массив структур и использовать для цикла. Если количество функций будет небольшим, то не будет никакого большого различия в производительности в карте и массиве. Что-то подобное для кодирования ниже будет работать
class MyClass
{
//........
double GetX();
double GetSomethingElse();
double GetT();
double GetRR();
//........
};
typedef double (MyClass::*MemFuncGetter)();
struct FuncTable
{
const char* m_pFuncName;
MemFuncGetter m_pFuncPtr;
};
class Processor
{
public:
void Process(Myclass& m, string);
};
static FuncTable descrToFuncMap[]
{
{ "X", &MyClass::GetX},
{ "SomethingElse", &MyClass::GetSomethingElse },
{ "RR", &MyClass::GetRR},
{ "T", &MyClass::GetT}
};
void Processor::Process(MyClass& ms, const std::string& key)
{
int functablesize = sizeof(descrToFuncMap)/sizeof(descrToFuncMap[0])
for(int i=0; i< functablesize; ++i)
{
if( strcmp(key.c_str(), descrToFuncMap[i].m_pFuncName)==0)
{
MemFuncGetter memFunc=descrToFuncMap[i].m_pFuncPtr;
double dResult=(ms).*memFunc();
std::cout<<"Command="<<key<<"result="<<result<<std::end;
break;
}
}
}
Я изменился бы
void Processor::Process(MyClass ms, std::string key)
кому:
void Processor::Process(const MyClass& ms, const std::string& key)
Не смотрите плохой побочный эффект на данный момент. Вероятно, с повышением:: функционируйте как значение карты, это будет легче в будущем.