经过一番搜索后,我还没有找到解决该问题的现有问题。如果我错过了什么,我深表歉意。

我有一个带有params结构和setter的基类。我想重新定义派生类中的params结构,并通过基类指针对其进行设置。例如以下内容。

class A
{
public:
    struct paramsType
    {
        int a;
        int b;
    };

protected:
    paramsType params;

public:
    void setParams(const paramsType& params) { this->params = params; }
};

class B : public A
{
public:
    struct paramsType
    {
        int c;
        int d;
        int e;
    };
};

class C : public A
{
public:
    struct paramsType
    {
        int f;
    };
};

int main () {
    A* ptrB = new B();
    A* ptrC = new C();

    B::paramsType paramsB;
    paramsB.c = 0;
    paramsB.d = 1;
    paramsB.e = 2;

    C::paramsType paramsC;
    paramsC.f = 3;

    ptrB->setParams(paramsB);
    ptrC->setParams(paramsC);

    delete ptrB;
    delete ptrC;
}

我曾尝试将基类“setParams”虚拟化并在派生类中重新定义它,但是当我通过基类指针调用该方法时,它具有不兼容的类型。

在实际用例中,B和C共享大量在A中实现的功能。它们只是具有不同的参数集。我只能访问基类指针,但是会知道对象是B还是C。是否有一种优雅的方法可以解决此问题?

谢谢!

最佳答案

您不能重新定义类型,但是可以做的是为参数设置一个通用的基类。

因此,您可以将A::paramsType设为基类,并从中派生B::paramsTypeC::paramsType。然后将指向A::paramsType的指针存储在类A中。这样,您可以使用公共(public)基类来传递参数。

但是,为了访问B::paramsTypeC::paramsType的成员,您将需要简化继承层次结构。您可以在成员函数中实现它。如果B::paramsType是从A::paramsType派生的,它将能够访问A::paramsType的所有公共(public)和 protected 成员;对于C::paramsType同样如此。

它将是这样的:

class A
{
public:
    struct paramsType
    {
        virtual ~paramsType() = default;
        int a;
        int b;
    };

protected:
    std::unique_ptr<paramsType> params;

public:
    void setParams(std::unique_ptr<paramsType> params) { this->params = std::move(params); }
};

class B : public A
{
public:
    struct paramsType : A::paramsType
    {
        int c;
        int d;
        int e;
    };

private:
    B::paramsType* getParams() { return dynamic_cast<B::paramsType*>(params.get()); }
};

工作版本here

关于c++ - C++多态数据结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61761048/

10-09 23:02