C++中的静态函数
Static Functions in C++
我已经在这里阅读了一些关于静态函数的文章,但仍然遇到实现问题。
我正在编写一个 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++丰富多彩历史的语言来说,这正是事实。请看这里阅读书籍建议。
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 检查编译时是否存在静态函数
- 名称隐藏对静态函数继承的实例使用
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- 类中静态函数C++意外结果
- 在工人类中使用不同类的静态函数进行实验
- 类 Referention 中C++回调函数引用非静态函数
- 指向模板上下文中的成员函数或静态函数的指针
- 如何检测 Clang AST C++中的静态函数
- 内联asm编译器屏障(内存阻塞器)是算作外部函数,还是算作静态函数调用
- 如何在静态函数中使用成员函数数组
- (2 问题)"类"类型重新定义(即使 #pragma 一次),以及静态函数内的静态成员对象初始化?
- 生成代码(在编译时)以调用模板的每个实例化的静态函数
- C++无法访问或使用静态函数
- 如何将 cpp 文件中的静态函数公开给其他文件
- 将函数的引用设置为其他 c++ 文件中的非静态函数
- 方法的静态函数的等价性
- 扩展包含静态函数的类
- 非静态函数可以访问静态变量吗?
- 调用非静态函数作为谓词?