22

I've read a few posts on here about static functions, but still am running into trouble with implementation.

I'm writing a hardcoded example of Dijkstra's algorithm for finding the shortest path.

Declared in Alg.h:

static void dijkstra();

Defined in 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

I want to call my function from main without an object. When I had all of this code in Main.cpp, it worked perfectly. Splitting it up into separate files caused the error Main.cpp:15: error: ‘dijkstra’ was not declared in this scope.The posts I came across when searching SE gave me me the impression that to do this, I needed to make that method static, yet I still have no luck.

What am I doing wrong?

Main.cpp:

#include <iostream>
#include "Alg.h"

int main() { 

    dijkstra();
    return 0; 
}

Edit: Added full header file, 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

Original all-in-one working Main.cpp file: http://pastebin.com/67u9hGsL

Ladybro
  • 756
  • 2
  • 9
  • 30
  • 3
    Please provide the full context of your header file. I'm guessing that `dijkstra` is supposed to be a class static? – CB Bailey Dec 03 '13 at 22:28
  • 1
    The definition of a static member function cannot contain the keyword `static`. Your attempt to define `static void Alg::dijkstra() {` will immediately trigger a compile error in `Alg.cpp`. Yet, you report a completely different error. And you claim that this code "worked" in `main.cpp`. This means that you posted fake code. Your claims are unrealistic. Post real code, please. – AnT stands with Russia Dec 03 '13 at 22:36
  • What is `Alg`??? Is it a class? Is it a namespace? – AnT stands with Russia Dec 03 '13 at 22:40
  • @AndreyT Alg is a class. See the edit. – Ladybro Dec 03 '13 at 22:44
  • 1
    @user3063527: Er... The code you linked in pastebin is completely different with regard to the issues in question. There's no `Alg` in that code. There's no `static` in that code. – AnT stands with Russia Dec 03 '13 at 23:13
  • @AndreyT Correct, exactly as I stated above. The code works, but I'm now facing errors when trying to separate it into different files. Thanks for all your help! – Ladybro Dec 03 '13 at 23:23
  • @user3063527: In that case you have to explain where `Alg` came from and why you are trying to use `static` in the first place. Nothing of that is necessary to just "separate it into different files". – AnT stands with Russia Dec 03 '13 at 23:37
  • Asking again http://stackoverflow.com/questions/20363761/calling-functions-from-main-in-c - big -1 ! –  Dec 03 '13 at 23:39

8 Answers8

29

You should call it this way:

Alg::dijkstra();

Limitations

  • Can't call any other class functions that are not static.
  • Can't access non static class data members.
  • Can instantiate an object via new class() when constructor is private/protected. E.g. a factory function.
egur
  • 7,830
  • 2
  • 27
  • 47
10

You can just use a namespace instead of having a class with all static members.

Alg.h:

namespace Alg
{
   void dijkstra();
}

and in Alg.cpp

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

in main.cpp

#include "Alg.h"

int argc, char **argv)
{
  Alg::dijkstra();

  return 1;
}
user3053099
  • 136
  • 2
6

Are you sure the function is supposed to be static?

It looks as if you want just a function? in your header file:

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

in your cpp file

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

in your main file:

#include "yourcppfile.h"

int main(int argc, char **argv) {
    dijkstra();
}

if you really want a static function you have to put it into a nested class:

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

the implementation somewhere in a cpp file

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

and then in your cpp file where the main resides

#include "your header file.h"

int main(int argc, char **argv) {
  Alg::dijkstra();
}
Alexander Oh
  • 24,223
  • 14
  • 73
  • 76
3

If I remember right any 'static' function is limited to the module in which it is implemented. So, 'static' prevents using the function in another module.

VladimirM
  • 817
  • 5
  • 7
1

In your header file Alg.h:

#ifndef __ALG_H__
#define __ALG_H__

namespace Alg {

    void dijkstra();

}

#endif

The include guards are necessary if you plan to include the header in more than one of your cpp files. It seems you would like to put the function in a namespace Alg, right?

In Alg.cpp:

#include "Alg.h"

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

Then, in main.cpp you call it with full namespace qualification:

#include "Alg.h"

int main() {

    Alg::dijkstra();

}

If you just want to distribute your code over several files, I don't see why the function should be declared static.

blackbird
  • 957
  • 12
  • 18
0

You are confusing the 'static' keyword for local functions, with the 'static' keyword used in a class to make a function a class function and not an object function.

Remove static the first line of Alg.cpp and in the header file. This will allow Alg.o to contain global symbols that main can refer to and the linker can link.

You still need to call Alg::dijkstra() as was stated by @egur.

After this you may still get errors. The way you are using Alg:: is more like a namespace than a 'class' definition.

KeithSmith
  • 774
  • 2
  • 8
  • 26
0

Now that we have the complete declaration of your class Arg, it feels like the singleton design pattern could be useful:

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

blackbird
  • 957
  • 12
  • 18
0

The key here is the ‘dijkstra’ was not declared in this scope error.

Take your all-in-one source file and remove the main function. Make a new source file with this in it:

void dijkstra();
void output();

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

The all-in-one cpp without a main plus this file above should compile together and give you the same result as before with one source, as it does for me. You will get a duplicate symbol _main error if you forgot to remove the main from the algorithm file.

No static needed.


My answer here fails to touch on good practices on header files, that is, you would want to include those function declarations in a .h file. It solves the compile-time error though.

You may want to find a good book to help you through some of the machinery of C++, where program context (in a linguistic sense) can change the meaning of keywords. This can be bewildering, and it proves to be exactly that for a language with as much colorful history as C++. Take a look here for book suggestions.

Community
  • 1
  • 1
Prashant Kumar
  • 20,069
  • 14
  • 47
  • 63