如何将具有不同成员变量类型的两个类和不同的构造函数制作到派生/基类或模板类中?

发布于 2025-02-13 12:20:45 字数 867 浏览 1 评论 0原文

class Data
{
public:
    int i;
};
auto cmp = [](const Data& d1, const Data& d2) { return d1.i > d2.i; };

class A
{
private:
    queue<Data> q;
public:
    A() {};

    void func() {
        int cnt = 0;
        while (!q.empty()) {
            std::cout << cnt++ << std::endl;
            q.pop();
        }
    }
};

class B
{
private:
    priority_queue<Data, vector<Data>, decltype(cmp)> q;
public:
    B() :q(cmp) {};

    void func() {
        int cnt = 0;
        while (!q.empty()) {
            std::cout << cnt++ << std::endl;
            q.pop();
        }
    }
};

我定义了两个类别的A和B. As Shis,他们的成员func是相同的,但是具有不同的成员变量类型q和不同的构造函数。

因此,我可以将A和B分为两个基类派生的两个类(但是在基类中使用func)或将它们放入模板类?(也就是说,我只想写<<代码> func 一次..) 如果可以的话,如何?

class Data
{
public:
    int i;
};
auto cmp = [](const Data& d1, const Data& d2) { return d1.i > d2.i; };

class A
{
private:
    queue<Data> q;
public:
    A() {};

    void func() {
        int cnt = 0;
        while (!q.empty()) {
            std::cout << cnt++ << std::endl;
            q.pop();
        }
    }
};

class B
{
private:
    priority_queue<Data, vector<Data>, decltype(cmp)> q;
public:
    B() :q(cmp) {};

    void func() {
        int cnt = 0;
        while (!q.empty()) {
            std::cout << cnt++ << std::endl;
            q.pop();
        }
    }
};

I define two classes A and B.As seen, their member func is the same, but with different member variable type q and different constructor.

So could I make A and B into two class derived from one base class (but with func in base class) or make them into a template class?(That is to say, I only want to write func once..)
If could, then how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

氛圍 2025-02-20 12:20:45

在这两种情况下,看来您只是在擦除收集类中的项目数量。如果是这样,让我们​​保持简单。

void func() {
    queue<Data> empty_queue;
    cout << "About to erase a queue of size " << q.size() << "\n";
    q.swap(empty_queue);
}

或者

void func() {
    priority_queue<Data, vector<Data>, decltype(cmp)> empty_queue;
    cout << "About to erase a queue of size " << q.size() << "\n";
    q.swap(empty_queue);
}

我要推荐一种继承策略,其中A和B来自基本模板类。但是在编码之后,我不喜欢从表面上的排队课程中得出的想法。您不能诚实地说A或B是队列的“是”。但这是我写的,我不喜欢它。

template <typename T>
class Base
{
protected:
    T q;

public:
    void func()
    {
        T empty_queue;
        q.swap(empty_queue);
    }
};

class A : public Base<queue<Data>>
{
public:
    A() {};
};

class B : public Base<priority_queue<Data, vector<Data>, decltype(cmp)>>
{
public:
    B() {}
};

一种更好的方法可能只编写一个模板函数:

template <typename T>
void EraseCollectionClass(T& t) {
    T empty;
    t.swap(empty);
}

然后保留您的原始实现:

class A
{
private:
    queue<Data> q;
public:
    A() {};

    void func() {
        EraseCollectionClass(q);
    }
};

class B
{
private:
    priority_queue<Data, vector<Data>, decltype(cmp)> q;
public:
    B() :q(cmp) {};

    void func() {
        EraseCollectionClass(q);
    }
};

In both cases, it looks like you are just trying to count the number of items in a collection class before erasing it. If that's the case, let's just keep it simple.

void func() {
    queue<Data> empty_queue;
    cout << "About to erase a queue of size " << q.size() << "\n";
    q.swap(empty_queue);
}

OR

void func() {
    priority_queue<Data, vector<Data>, decltype(cmp)> empty_queue;
    cout << "About to erase a queue of size " << q.size() << "\n";
    q.swap(empty_queue);
}

I was about to recommend an inheritance strategy where A and B derived from a Base template class. But after I coded it, I didn't like the idea of deriving from what's ostensibly a queue class. You can't honestly say that A or B are "is a" of a queue. But here's what I wrote and I don't like it.

template <typename T>
class Base
{
protected:
    T q;

public:
    void func()
    {
        T empty_queue;
        q.swap(empty_queue);
    }
};

class A : public Base<queue<Data>>
{
public:
    A() {};
};

class B : public Base<priority_queue<Data, vector<Data>, decltype(cmp)>>
{
public:
    B() {}
};

A better approach might to just write a single template function:

template <typename T>
void EraseCollectionClass(T& t) {
    T empty;
    t.swap(empty);
}

And then keep your original implementations:

class A
{
private:
    queue<Data> q;
public:
    A() {};

    void func() {
        EraseCollectionClass(q);
    }
};

class B
{
private:
    priority_queue<Data, vector<Data>, decltype(cmp)> q;
public:
    B() :q(cmp) {};

    void func() {
        EraseCollectionClass(q);
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文