0

For some reason the following code gives a compiler error in DevC++: [Error] cannot declare member function 'static double* Sort::bubbleSort(double*, int)' to have static linkage [-fpermissive]

BubbleSort.cpp:

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

int main(int argc, char** argv) {

    double list[] = {4.0, 4.5, 3.2, 10.3, 2.1, 1.6, 8.3, 3.4, 2.1, 20.1};
    int size = 10;
    double* sortedList = Sort::bubbleSort(list, size);

    return 0;
}

Sort.h:

class Sort
{
    public: 
        static double* bubbleSort (double list[], int size);    
}
;

Sort.cpp:

#include "Sort.h"
#include <algorithm> // std::swap

static double* Sort::bubbleSort (double list[], int size)
{
    bool changed = true;

    do
    {
        changed = false;
        for (int j = 0;  j < size - 1; j++)
        {
            if (list[j] > list[j +1])
            {
                std::swap(list[j], list[j + 1]);
                changed = true;
            }
        }
    } 
    while (changed);

    return list; // return pointer to list array    
}

Essentially, I'm trying to call the bubbleSort function without creating a Sort object. The code works fine if I create an object first.

What could be causing the error?

Thanks for any suggestions.

navig8tr
  • 1,724
  • 8
  • 31
  • 69

4 Answers4

5

The static modifier goes in Sort.h, but not in Sort.cpp.

That's because it means two different things in the two contexts.

When used inside a class declaration, static indicates that the method it refers to is a class method (that you should use without a object reference), rather than a instance method (that you need a object reference to invoke).

When used inside the implementation file (i.e. outside of a class declaration), it indicates that the method it refers to should have static linkage, which means it should not be made visible from outside the object file that contains it. From an object oriented point of view, these functions are private to the file that contains them. It's pretty obvious that this cannot work if other files (which are using your class) should access the method.

Giulio Franco
  • 3,170
  • 15
  • 18
  • 1
    Its a wacky holdover from C. – FlavorScape Nov 04 '13 at 02:10
  • @Giulio Franco: Does that mean you could add the static keyword to private member functions without causing an error? – maddin45 Nov 04 '13 at 09:33
  • I'm not sure but I think not. The method still needs to be visible from the outside, in order to be linked by the linker. Nothing forces you to put all the methods in the same file, and so also private methods should be publicly visible. Anyway, you can prevent a method from being seen by using a static function (function, not method) rather than a private method. – Giulio Franco Nov 04 '13 at 21:42
  • of course the static function cannot access private members of the class. That's an issue, though. – Giulio Franco Nov 04 '13 at 21:43
0

Remove the static keyword in the .cpp file. Also, you do not need to return the pointer list since only the contents of the array change change, not the array itself. You can keep using the pointer that you put into the function. sortedList will point to the same memory location as list at the end of your main function.

maddin45
  • 737
  • 7
  • 17
0

If all that is in your Sort class is this one static member, there is absolutely no need for a class.

double* bubbleSort (double list[], int size)
{
    bool changed = true;

    do
    {
        changed = false;
        for (int j = 0;  j < size - 1; j++)
        {
            if (list[j] > list[j +1])
            {
                std::swap(list[j], list[j + 1]);
                changed = true;
            }
        }
    } 
    while (changed);

    return list; // return pointer to list array    
}

Additionally, there is no need to return the pointer to the list because you are modifying the list as you sort it (double list[] is the same as double* list, and since you are changing the values in your routine, the pointer to the first element will still be the same, but the values in the array will be swapped around).

void bubbleSort (double list[], int size)
{
    bool changed = true;

    do
    {
        changed = false;
        for (int j = 0;  j < size - 1; j++)
        {
            if (list[j] > list[j +1])
            {
                std::swap(list[j], list[j + 1]);
                changed = true;
            }
        }
    } 
    while (changed);
}
Zac Howland
  • 15,777
  • 1
  • 26
  • 42
  • Thanks for the suggestions. There are other members, but not many. I certainly could get away without using a class, but I thought it would be good practice. – navig8tr Nov 04 '13 at 00:53
  • In C++, if it does not have to be in a class (e.g. it doesn't use any class members), there is no reason to have it in a class. This is a hard habit to break for people coming from languages like Java and C#. – Zac Howland Nov 04 '13 at 01:35
0

You should make the function free-standing and if you need a class method, make it call the free-standing function with the correct parameters.

RamblingMad
  • 5,332
  • 2
  • 24
  • 48