在C++中,静态函数调用非静态函数。

13

我有一个类像这样::

Class Test
{
  public:
  void Check(){//dosomething};
  static void call(){//I want to call check()};
};
因为call()是一个静态成员,所以它不能调用非静态函数,所以我认为在call()中使用Check()是创建Test指针,然后指向Check(),但我认为这不好,是否有更好的方法? 我可以重写所有静态函数中的内容,因此我不需要再次调用Check(),但我想要重用Check()中的代码并避免重复代码。

不清楚你想做什么。你可以用语言想出无数种方法来绕过它,但最终你处于这种情况的原因是你的需求没有意义。在call中没有对象上下文。你为什么认为你需要这样做? - Lightness Races in Orbit
为什么不将Check声明为静态函数? - Summer_More_More_Tea
1
你需要一个 test 类的实例来调用任何非静态函数(即 this 指针)。 - mark
1
你正在错误的方向上解决问题,而且你并没有告诉我们这个潜在问题是什么。 - Kerrek SB
4个回答

14

由于您需要一个实例,因此您可以创建一个实例,使用静态实例或将其传递给call()

Class Test
{
  private:
  static Test instance;

  public:
  void Check(){//dosomething};
  // use one of the following:
  static void call(Test& t){ t.check(); };
  static void call(){ Test t; t.check(); };
  static void call(){ instance.check(); };
};

3
如何设置实例变量? - JavaRunner

4
这听起来像是存在一些糟糕的设计。
无论如何,你可以在call中创建Test的实例,并调用该实例的Check方法。然后call的实现应该像这样:
void call(){
  Test test;
  test.Check();
}

然而,请注意如果 Check 对 Test 的成员进行操作,它当然只适用于已创建的 Test 对象。我建议重新考虑是否真正需要将 call 设为静态,或者将 Check 设为非静态。


在类外,函数调用应该是 "void Test**::**call() { ...}"。 - Eswaran Pandi

0
非静态成员函数和静态成员函数的主要区别在于后者没有任何对象。它仍然具有与所有其他成员相同的访问权限。
当您想从静态成员调用非静态成员函数时,仍然需要提供一个对象。通常,静态成员函数将传递一些上下文以获取对象。从您的问题听起来,似乎静态函数和非静态函数旨在执行不需要对象的类似操作。在这种情况下,最好将不依赖于任何对象的公共部分因素化为另一个函数,然后从call()Check()中调用该函数。
void Test::call() {
    common();
    // ... other code
}
void Test::Check() {
    common();
    // ... other code, possibly depending on "this"
}
void Test::common() {
    // logic shared by both call() and Check() but not depending on "this"
}

如果通用代码需要一个对象,那么唯一的方法就是在静态成员函数中创建一个对象。


0

这个问题没有简单的答案。有很多事情你可以做,但哪种方法是正确的取决于你的代码意义。这是一个设计问题,而不是一个编程问题。

你已经提出了各种编程技巧,比如创建一个Test指针(实际上你不需要一个Test指针,只需要一个Test对象)。我可以建议更多的技巧,例如你可以重写call()使其不是静态的,或者(几乎相同的事情)你可以将Test指针作为call()的参数传递并使用它,或者你可以创建一个全局的Test对象并使用它。这些都没有解决问题的核心。要回答你的问题,你必须问自己一些问题,比如,为什么我首先要将call()设置为静态的,为什么一个静态函数需要调用一个非静态函数。

如果你能解释清楚这些问题,那么就更容易给出更具体的建议。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接