C ++: Как я могу использовать разные реализации методов с одним и тем же классом данных?

0
задан Igor G 1 March 2019 в 11:49
поделиться

2 ответа

Возможное менее совершенное решение моего собственного вопроса:

1. Не беспокойтесь о методах и используйте вместо этого отдельно стоящие функции.

struct CoreData
{
    int   m_x;
    ~CoreData();
};

void TeamA_init(CoreData& data);
void TeamA_push_back(CoreData& data, Whatever args);
Iter TeamA_begin(CoreData& data);

bool TeamB_init(CoreData& data, Other args);
bool TeamB_push_back(CoreData& data, Whatever args);
X* TeamB_begin(CoreData& data);

//---------------------  Usage:
void ServiceOfTeamA::CallServiceOfTeamB(ServiceOfTeamB* srv)
{
    CoreData     d;
    TeamA_init(d);
    srv->Process(&d);
    TeamA_begin(d);
}

void ServiceOfTeamB::Process(CoreData* d)
{
    TeamB_push_back(*d, 567);
}

- Что мне не нравится в этом подходе, так это недружественный синтаксис, никакой RAII и все члены данных не являются открытыми. Это C, а не C ++.

+ С другой стороны, этот подход предлагает неограниченные возможности настройки. Нет ограничений в выборе правильной функции для задачи. Никаких накладных расходов на память, никаких накладных расходов на выполнение (то есть, технически компилятор имеет те же возможности вставки и оптимизации, что и методы, которые эти свободные функции будут использовать).

0
ответ дан Igor G 1 March 2019 в 11:49
поделиться

Возможное менее совершенное решение моего собственного вопроса:

3. Бросьте код на милость де-факто определенного поведения reinterpret_cast.

// This is a standard layout class.
// It is the only class with data members;
// derived classes never append new data members.
class CoreData
{
public:
    // Could be either explicit conversion function
    // or implicit conversion operator.
    template <typename Final>
    // requires <LayoutCompatibleWithCore Final>
    Final& As()
    {
        return reinterpret_cast<Final&>(*this);
    }

protected:
    ~CoreData();

    int      m_x;
};

// No extra data members appended. No extra invariants imposed.
// This class is also a standard layout type,
// fully layout-compatible with CoreData.
class TeamA : public CoreData
{
public:
    void push_back(Whatever args);
    Iter begin();
};

class TeamB : public CoreData
{
public:
    bool push_back(Whatever args);
    X* begin();
};

//---------------------  Usage:
void ServiceOfTeamA::CallServiceOfTeamB(ServiceOfTeamB* srv)
{
    TeamA        d;
    srv->Process(&d);
    d.begin();
}

void ServiceOfTeamB::Process(CoreData* core)
{
    TeamB&       d = core->As<TeamB>();
    d.push_back(567);
}

- Однако такие приемы запрещены стандартом. Поэтому я тоже должен отказаться от этого подхода.

+ Если бы это было законно, он предложил бы лучший синтаксис из трех, синтаксис, четко показывающий эталонную семантику, с RAII и без пессимизации.

P.S. Недействительность такого подхода опускает меня. Весь смысл совместимости компоновки дает возможность передавать данные между ABI-совместимыми процессами или общими компонентами. Жаль, что это не позволяет передавать данные между частями одного и того же приложения ...

0
ответ дан Igor G 1 March 2019 в 11:49
поделиться
Другие вопросы по тегам:

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