简体   繁体   中英

Extend struct in inheriting class

Is it possible to declare a struct in a parent class and define it in the inheriting child class (in every child class it should look different)?

An example would look like this:

class parent
{
    virtual struct AlwaysDifferentStructure;

    //Some methods here
    //...
};

class child1 : public parent
{
    struct AlwaysDifferentStructure
    {
        int foo;
    }

    //Some methods here
    //...
};

class child2 : public parent
{
    struct AlwaysDifferentStructure
    {
        char* foo;
        float bar;
        double foobar;
    }

    //Some methods here
    //...
};

So actually what I am trying do deal with is the following: I got a parent class shader and a lot of inheriting classes (ie simple_color_shader ). Each shader has its own vertex structure. Now I want to render an object with one of these shader but I don't know how the vertex struct exactly looks like because it is always different but I need it. So I thought that I could just redeclare the struct in all the children and gain access through the parent. So in the object class it basically looks like this:

class object
{
    parent* m_pParent;
    AlwaysDifferentStructure* m_structArray;
};

(Just ask if you don't understand what I'm trying to tell you; my english is not that good)

My question is: Is this even possible and if yes i would appreciate if someone could tell me how.

something like this can be accomplished with the Curiously recurring template pattern

template <typename derived>
class parent
{
    void someMethod ()
    {
        typename derived::AlwaysDifferentStructure x;

        x.foo;
    }
};

class child1 : public parent <child1>
{
    struct AlwaysDifferentStructure
    {
        int foo;
    }

    //Some methods here
    //...
}

class child2 : public parent <child2>
{
    struct AlwaysDifferentStructure
    {
        char* foo;
        float bar;
        double foobar;
    }

    //Some methods here
    //...
}

For the OP found the snippets posted in the comments to be good suggestions, I'm posting them here for future readers.


Here is a possible approach, as mentioned in the comments:

class parent { };
class child1 : public parent { };
class child2 : public parent { };

template<typename>
struct AlwaysDifferentStructure;

template<>
struct AlwaysDifferentStructure<child1> {
    int foo;
};

template<>
struct AlwaysDifferentStructure<child2> {
    char* foo;
    float bar;
    double foobar;
};

int main() {
    AlwaysDifferentStructure<child1> c1t;
    c1t.foo = 42;
    AlwaysDifferentStructure<child2> c2t;
    c2t.foo = new char{'c'};
    c2t.bar = .42;
    c2t.foobar = 0.;
}

As another viable solution, you can do this:

class parent {
    //Some methods here
    //...
};

class child1 : public parent {
public:
    auto alwaysDifferentStructure() {
        struct S {
            int foo;
        } s;

        return s;
    }
};

class child2 : public parent {
public:
    auto alwaysDifferentStructure() {
        struct S { 
            char* foo;
            float bar;
            double foobar;
        } s;

        return s;
    }
};

int main() {
    auto c1t = child1{}.alwaysDifferentStructure();
    c1t.foo = 42;
    auto c2t = child2{}.alwaysDifferentStructure();
    c2t.foo = new char{'c'};
    c2t.bar = .42;
    c2t.foobar = 0.;
}

Note that this second example requires C++14.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM