Issue with static member function and derived clas

2019-06-14 17:33发布

问题:

I have a class with static member function (which is necessary). To be able to use non-static members of the class. I defined a Static_This which is a pointer to the class.

template<class T>
class Energy_Minimizer
{
protected:

    static Energy_Minimizer* Static_This;

    Petsc_Vector<T>* Gradient;
    Petsc_Vector<T>* Solution;
    static int Form_Function_and_Gradient(Petsc_Vector<T> *Solution_,Petsc_Vector<T>  *Gradient_, PetscReal *Function_Value_);
public:
    Energy_Minimizer(MPI_Comm Communicator_);
    void Add_Term(vector<int>& Indexes, void* Coefs, string Function_Name_);
    virtual void Total_Energy()=0;
};

I set the Static_This in the constructor of the class.

template<>
Energy_Minimizer<double>::Energy_Minimizer(MPI_Comm Communicator_)
{
    Communicator = Communicator_;
    Static_This = this;
        ...
}

And can access to non-static virtual function:

int Energy_Minimizer<double>::Form_Function_and_Gradient(Petsc_Vector<double> *Solution_,Petsc_Vector<double>  *Gradient_, PetscReal *Function_Value_)
{

Static_This->Solution = Solution_;
    Static_This->Gradient = Gradient_;

    // Call the user-defined routine to construct the function value, gradient
    Static_This->Total_Energy();

    return 0;
}

I implement the virtual function Total_Energy() in the derived class:

class Strain_Solver : public Energy_Minimizer<double>;

void Strain_Solver::Total_Energy()
{
        ****** Here problem occurs ******
    this->Add_Term(ij_Indexes, NULL , string("Alpha_Term")); 
}

I call the function of the base class from derived class virtual function. The only problem I have is that as soon as I call a member function of the base class from my derived class then the data (here Solution) gets corrupted. i.e. When I call Add_Term function in above example the Solution vector of the base class suddenly gets corrupted. It is like it gets de-allocated.

回答1:

It sounds like the problem originates in the derived class, and with this kind of design it could be anywhere. You don't seem to be using any language constructs for the intended purpose… you're breaking all the rules and it's not clear why.

When I call Add_Term function in above example the Solution vector of the base class suddenly gets corrupted. It is like it gets de-allocated.

Ignoring the code, when you increase the size of a std::vector, it may reallocate (that is, deallocate and move) the contained objects to a larger memory block. Therefore you can't use pointers or iterators into a std::vector whose size increases.

If some part of the program keeps track of a thing inside ij_Indexes across a call to Add_Term, it must

  • Use integer offsets (std::size_t is the best type) and the subscript operator (syntax like ij_Indexes[offset]) or
  • The type of ij_Indexes should be changed to the container std::deque, which doesn't reallocate but isn't a flat array and would be incompatible with a C-based math library such as you appear to be using.


回答2:

Your Static_This member is not static. Even if it were, there's only one instance of a static field (data member), but there can be multiple instances of a class. Which instance would your Static_This member point to?

It seems like an odd design anyway. If you post your real code (or at least describe it), I'm sure someone will suggest you a better design.