C++中的静态函数

Static Functions in C++

本文关键字:静态函数 C++      更新时间:2023-10-16

我已经在这里阅读了一些关于静态函数的文章,但仍然遇到实现问题。

我正在编写一个 Dijkstra 算法的硬编码示例,用于查找最短路径。

在阿尔格声明:

static void dijkstra();

在 Alg.cpp 中定义:

static void Alg::dijkstra() { 
//Create Map
Initialize();
//Loop to pass through grid multiple times
for(int i=0; i<5; i++)
{   
    current=1;  
    while(current!=6)
    {
        //Iterate through and update distances/predecessors
        //For loop to go through columns, while current iterates rows
        for(int j=1; j<7; j++)
        {
            //Check if distance from current to this node is less than
            //distance already stored in d[j] + weight of edge
            if(distanceArray[current][j]+d[current]<d[j])
            {
                //Update distance
                d[j] = distanceArray[current][j]+d[current];
                //Update predecessor
                p[j] = current;
            }    
        }
        //Go to next row in distanceArray[][]
        current++;
    } //End while

} //End for
output();
} //End Dijkstras

我想在没有对象的情况下从 main 调用我的函数。当我在 Main.cpp 中拥有所有这些代码时,它运行良好。将其拆分为单独的文件会导致错误Main.cpp:15: error: ‘dijkstra’ was not declared in this scope 。我在搜索 SE 时遇到的帖子给我的印象是,要做到这一点,我需要使该方法成为静态的,但我仍然没有运气。

我做错了什么?

主.cpp:

#include <iostream>
#include "Alg.h"
int main() { 
    dijkstra();
    return 0; 
}

编辑:添加了完整的头文件,Alg.h:

#ifndef Alg_
#define Alg_
#include <iostream>
#include <stack>
using namespace std;
class Alg
{
    public:
        void tracePath(int x);
        void output();
        void printArray();
        void Initialize();
        static void dijkstra();
        int current, mindex;
        int distanceArray[7][7]; //2D array to hold the distances from each point to all others
        int d[6]; //Single distance array from source to points
        int p[6]; //Array to keep predecessors 
        int copyD[6]; //Copy of d[] used for sorting purposes in tracePath()
        int order[6]; //Contains the order of the nodes path lengths in ascending order
}; //End alg class
#endif

原始多合一工作主.cpp文件:http://pastebin.com/67u9hGsL

你应该这样称呼它:

Alg::dijkstra();

局限性

  • 不能调用任何其他非静态类函数。
  • 无法访问非静态类数据成员。
  • 当构造函数私有/受保护时,可以通过new class()实例化对象。 例如,工厂函数。

您可以只使用命名空间,而不是拥有包含所有静态成员的类。

阿尔格:

namespace Alg
{
   void dijkstra();
}

在阿尔格.cpp

namespace Alg
{
   void dijkstra()
   {
     // ... your code
   }
}

在主要.cpp

#include "Alg.h"
int argc, char **argv)
{
  Alg::dijkstra();
  return 1;
}

你确定这个函数应该是静态的吗?

看起来你只想要一个功能?在头文件中:

#ifndef DIJKSTRA_H
#define DIJKSTRA_H
void dijkstra(); 
#endif

在您的 CPP 文件中

void dijkstra() {
   /* do something */
}

在您的主文件中:

#include "yourcppfile.h"
int main(int argc, char **argv) {
    dijkstra();
}

如果你真的想要一个静态函数,你必须把它放到一个嵌套类中:

class Alg {
  public:
    static void dijkstra();
  /* some other class related stuff */
}

CPP 文件中某处的实现

void Alg::dijkstra() {
  /* your code here */
}

然后在主文件所在的 cpp 文件中

#include "your header file.h"
int main(int argc, char **argv) {
  Alg::dijkstra();
}

如果我没记错的话,任何"静态"函数都仅限于实现它的模块。因此,"静态"会阻止在另一个模块中使用该函数。

在头文件中Alg.h

#ifndef __ALG_H__
#define __ALG_H__
namespace Alg {
    void dijkstra();
}
#endif

如果您计划在多个 cpp 文件中包含标头,则包含保护是必需的。看来您想将函数放在命名空间Alg中,对吗?

在阿尔格.cpp:

#include "Alg.h"
void Alg::dijkstra() { /* your implementation here */ }

然后,在 main 中.cpp您可以使用完整的命名空间限定来调用它:

#include "Alg.h"
int main() {
    Alg::dijkstra();
}

如果您只想将代码分布在多个文件中,我不明白为什么要将该函数声明为 static .

您将本地函数的"static"关键字与类中使用的"static"关键字混淆,以使函数成为类函数而不是对象函数。

static Alg.cpp 的第一行和头文件中删除。这将允许 Alg.o 包含main可以引用且链接器可以链接的全局符号。

您仍然需要按照@egur所述致电Alg::dijkstra()

在此之后,您可能仍然会收到错误。您使用 Alg:: 的方式更像是一个namespace,而不是"类"定义。

现在我们已经有了您的类Arg的完整声明,感觉单例设计模式可能很有用:

http://en.wikipedia.org/wiki/Singleton_pattern

这里的关键是‘dijkstra’ was not declared in this scope错误。

获取多合一源文件并删除main功能。创建一个包含以下内容的新源文件:

void dijkstra();
void output();
int main(int argc, char *argv[]) {
    dijkstra();
    output();
    return 0;
}

没有main的多合一 cpp 加上上面的这个文件应该一起编译,并为您提供与以前相同的结果,就像它对我所做的那样。如果您忘记从算法文件中删除 main,您将收到一个duplicate symbol _main错误。

无需static


我在这里的回答没有涉及头文件的良好实践,也就是说,您可能希望将这些函数声明包含在.h文件中。不过,它解决了编译时错误。

你可能想找到一本好书来帮助你完成一些C++机制,其中程序上下文(在语言意义上(可以改变关键字的含义。这可能令人眼花缭乱,事实证明,对于一种拥有C++丰富多彩历史的语言来说,这正是事实。请看这里阅读书籍建议。