多个类看起来几乎相同,但是使用一些不同的数据和函数

问题描述 投票:0回答:1

我有多个类,它们看起来几乎相同,作用几乎相同,但是定义和使用不同的数据,并且它们的某些功能工作不同(尽管它们具有相同的名称/签名)。

class SomeClass1{

    class UniqueData1{};
    UniqueData1 data;
    static UniqueData1 static_data;

    void doStuff1() {doWhatever( data);}
    void doStuff2() {doUniqueStuff( data);}

    void doUniqueStuff(UniqueData1 _data) {doABC( _data); doCDE();}

};

class SomeClass2{

    class UniqueData2{};
    UniqueData2 data;
    static UniqueData2 static_data;

    void doStuff1() {doWhatever( data);}
    void doStuff2() {doUniqueStuff( data);}

    void doUniqueStuff(UniqueData2 _data) {doMNO( _data); doPQR();}

};

有很多函数,如doStuff()和许多类。我如何解决此问题而无需复制粘贴?我当时在考虑模板和虚函数,但到目前为止还没有提出任何解决方案。

编辑:一些具有相同外观的功能需要调用做独特工作的功能。

c++ templates virtual-functions
1个回答
1
投票

嗯,很难确定您要解决的real问题是什么。但是,根据您提供的最低限度的示例,这就是使用模板的方法:

template <int I>
class SomeClass {
public:
    class UniqueData{};
    UniqueData data;
    static UniqueData static_data;
    void doStuff() { doWhatever(data); }
    void doStuff2() { doUniqueStuff(data); }
    void doUniqueStuff(UniqueData uniqueData);
};

void doCDE() { }
void doABC(SomeClass<1>::UniqueData) { }
void doPQR();
void doMNO(SomeClass<2>::UniqueData) { }

template<>
void::SomeClass<1>::doUniqueStuff(SomeClass<1>::UniqueData data) {
    doABC(data);
    doCDE();
}

template<>
void::SomeClass<2>::doUniqueStuff(SomeClass<2>::UniqueData data) {
    doMNO(data);
    doPQR();
}

int main() {
    SomeClass<1>().doStuff2();
    SomeClass<2>().doStuff2();
}

这里,模板实例具有其自己的唯一数据类型和两个功能。这两个函数专用于调用不同的函数。

编辑:您指定要UniqueData具有一些唯一成员。如果您愿意灵活,可以使用元组:

#include <functional>
#include <iostream>
#include <tuple>
#include <string>

template<typename T>
void doWhatever(T) { }

// This is now a variadic template. All arguments after id are packed into TUniqueDataMembers
template <int id, typename... TUniqueDataMembers>
class SomeClass {
public:
    // UnqiueData has a tuple member (with TUniqueDataMembers). It has one member of each template argument given
    class UniqueData {
    public:
        UniqueData() : data(std::make_tuple(TUniqueDataMembers{}...)) { }
        std::tuple<TUniqueDataMembers...> data;
    };
    UniqueData data;
    static UniqueData static_data;
    void doStuff() { doWhatever(data); }
    void doStuff2() { doUniqueStuff(data); }
    void doUniqueStuff(UniqueData uniqueData);
};

// Using a type definition saves some boilerplate, now that we're using multiple template arguments
using SomeClass1 = SomeClass<1, int>;
using SomeClass2 = SomeClass<2, double, std::string>;

void doCDE() { }
void doABC(SomeClass1::UniqueData data) {
    // Use std::get<index>(tuple) to access unique data
    std::cout << "int: " << std::get<0>(data.data) << "\n";
}
void doPQR() { }
void doMNO(SomeClass2::UniqueData data) {
    std::cout << "double: " << std::get<0>(data.data) << "\n";
    std::cout << "string: " << std::get<1>(data.data) << "\n";    
}

template<>
void SomeClass1::doUniqueStuff(SomeClass1::UniqueData data) {
    doABC(data);
    doCDE();
}

template<>
void SomeClass2::doUniqueStuff(SomeClass2::UniqueData data) {
    doMNO(data);
    doPQR();
}

int main() {
    SomeClass1 class1 {};
    std::get<0>(class1.data.data) = 42;
    class1.doStuff2();

    SomeClass2 class2 {};
    std::get<0>(class2.data.data) = 2.5;
    std::get<1>(class2.data.data) = "hello, world!";
    class2.doStuff2();
}
© www.soinside.com 2019 - 2024. All rights reserved.