Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
220 views
in Technique[技术] by (71.8m points)

c++ - Is there a way to declare a member in a way that will make it static in all derived classes?

I have several abstract classes that need to manage static vectors containing pointers to every instance of themselves. Here's a simplified example of how one of those classes looks:

class AbstractBase1
{
public:
    AbstractBase1()
    {
        allInstances_.push_back(this);
    }
    AbstractBase1(const AbstractBase1& source)
      : AbstractBase1()
    {
        //Copy data from source
    }
    AbstractBase1(const AbstractBase1&& source)
      : AbstractBase1()
    {
        //Copy data from source
    }
    virtual ~AbstractBase1()
    {
        //Find the index of 'this' with std::find and remove it from allInstances_
    }
    virtual void purelyVirtualMethod() = 0;
    static void doSomethingWithAllInstances()
    {
        for (AbstractBase1* ptr : allInstances_)
        {
            ptr->purelyVirtualMethod();
        }
    }
private:
    static std::vector<AbstractBase1*> allInstances_;
    //Some data that will be inherited
};

So rather than having to write all that code for every class that needs this functionality, I figured I would create an InstanceTracker class containing this functionality, and then have all those classes inherit from it. But I can't wrap my head around how this InstanceTracker class would look, since I don't want this class to manage a static vector of all its derived classes' instances. What I want is that each class that inherits from InstanceTracker will get their own static vector that will manage its instances.

Is there a way to achieve this or will I just have to write the instance-tracking code for every class that needs it?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You might use template:

template <typename Tag>
class AbstractBaseT
{
public:
    AbstractBaseT() { allInstances_.push_back(this); }
    AbstractBaseT(const AbstractBase1& source) : AbstractBaseT()
    {
        //Copy data from source
    }
    AbstractBaseT(AbstractBaseT&& source) : AbstractBase1()
    {
        //Move data from source
    }
    virtual ~AbstractBaseT()
    {
        //Find the index of 'this' with std::find and remove it from allInstances_
    }
    virtual void purelyVirtualMethod() = 0;
    static void doSomethingWithAllInstances()
    {
        for (AbstractBase1* ptr : allInstances_)
        {
            ptr->purelyVirtualMethod();
        }
    }
private:
    static std::vector<AbstractBaseT*> allInstances_;
    //Some data that will be inherited
};

and then

using AbstractBase1 = AbstractBaseT<struct tag1>;

or the CRTP way might also be useful:

struct AbstractBase2 : AbstractBaseT<AbstractBase2>
{
    // ...
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...