【问题标题】:Issue with static member function and derived class静态成员函数和派生类的问题
【发布时间】:2013-01-14 07:13:06
【问题描述】:

我有一个带有静态成员函数的类(这是必要的)。能够使用类的非静态成员。我定义了一个Static_This,它是一个指向类的指针。

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;
};

我在类的构造函数中设置了Static_This

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

并且可以访问非静态虚函数:

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;
}

我在派生类中实现了虚函数 Total_Energy():

class Strain_Solver : public Energy_Minimizer<double>;

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

我从派生类的虚函数中调用基类的函数。我唯一的问题是,一旦我从派生类调用基类的成员函数,数据(此处为解决方案)就会损坏。即当我在上面的示例中调用 Add_Term 函数时,基类的解决方案向量突然被破坏。就像它被取消分配一样。

【问题讨论】:

  • Static_This 不是static。如何在静态函数中访问它?看来您还没有发布实际的帖子。这是一个问题。如果您正在做某事并发布其他内容,并希望我们为您提供帮助?
  • 这是问题中的错字,我正在更正它
  • 你在这里试图做的似乎是一场暴行。多考虑一下并重新设计您的代码。也许私有继承可以解决您的问题?

标签: c++ inheritance static static-methods


【解决方案1】:

听起来问题出在派生类中,而通过这种设计,问题可能出现在任何地方。您似乎没有出于预期目的使用任何语言结构……您违反了所有规则,目前尚不清楚原因。

当我在上面的示例中调用 Add_Term 函数时,基类的解决方案向量突然损坏。就像它被取消分配一样。

忽略代码,当您增加std::vector 的大小时,它可能会将包含的对象重新分配(即释放 并移动)到更大的内存块。因此,您不能在大小增加的std::vector 中使用指针或迭代器。

如果程序的某些部分通过对Add_Term 的调用来跟踪ij_Indexes 中的某个事物,则它必须

  • 使用整数偏移量(std::size_t 是最好的类型)和下标运算符(语法如ij_Indexes[offset])或
  • ij_Indexes 的类型应更改为容器std::deque,它不会重新分配但不是平面数组,并且与您使用的基于 C 的数学库不兼容。

【讨论】:

  • 渐变不是 std::vector,它是一个包装类。此外,当我调用 this->Add_Term(ij_Indexes, NULL , string("Alpha_Term")); 时会出现问题在我没有做任何事情的第一行。
  • 就像你退出一个函数,函数的所有局部变量都被释放了,但我不知道为什么会发生在这里。
  • @Hesam 答案仍然有效,已编辑。这有点像在黑暗中拍摄,我只是提到一个与您描述的症状相匹配的常见错误。该错误很可能是其他原因,并且该站点可能无法为您提供帮助。但一定要考虑这种可能性。
  • 这种设计是什么意思?什么是更好的设计?
【解决方案2】:

您的 Static_This 成员不是静态的。即使是这样,静态字段(数据成员)也只有一个实例,但一个类可以有多个实例。您的 Static_This 成员将指向哪个实例?

无论如何,这似乎是一个奇怪的设计。如果你发布你的真实代码(或至少描述它),我相信有人会建议你更好的设计。

【讨论】:

    猜你喜欢
    • 2018-11-30
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 1970-01-01
    相关资源
    最近更新 更多