Указатели хранилища на функцию членства в карте

В конце концов, я решил, что, удалив 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>
8
задан 10 March 2009 в 16:19
поделиться

3 ответа

Выглядит хорошо мне, но для факта это 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();
6
ответ дан 5 December 2019 в 22:20
поделиться

Избегайте использования 'виртуальный' при использовании карт указателей функции. В этом контексте, с помощью 'виртуального' ключевого слова не поможет многому. Например,

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;
        }
    }     
 }
0
ответ дан 5 December 2019 в 22:20
поделиться

Я изменился бы

void Processor::Process(MyClass ms, std::string key)

кому:

void Processor::Process(const MyClass& ms, const std::string& key)

Не смотрите плохой побочный эффект на данный момент. Вероятно, с повышением:: функционируйте как значение карты, это будет легче в будущем.

0
ответ дан 5 December 2019 в 22:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: