tags:

views:

1326

answers:

5

I'm writing a C++ class to read input from a file into preallocated buffers called "chunks".

I want the caller to be able to call a public static Chunk class method called GetNextFilledChunk(), which

  1. Grabs a Chunk from an inactive chunk pool
  2. Fills the Chunk instance from the input stream using the Chunk's private member variables/functions
  3. Returns a pointer to the Chunk to the caller

But step 2 is giving me fits. No matter what I've tried, trying to get to the Chunk instance's private member variables/functions causes g++ 4.2.1 to emit errors.

Here's a piece of the class definition from the header file:

class Chunk
{
public:
                        Chunk();
...
    static Chunk*       GetNextFilledChunk();
...

private:
...
    ssize_t             m_ActualTextSize;
};

And here's part of the source file that shows the problem:

#include "Chunk.h"


Chunk::
Chunk*  GetNextFilledChunk()
{
    ...
    theChunk = sInactiveChunks.top();
    sInactiveChunks.pop();
    ...
    theChunk->m_ActualTextSize = TextSize();    // PROBLEM IS HERE
    ...

    return theChunk;
}

As shown, g++ complains that GetNextFilledChunk() is trying to access a private member of Chunk.

Then I thought, maybe it needs to be a "friend". But everything I've tried to do in header file to make GetNextFilledChunk() a friend results in an error. For instance:

friend static Chunk* GetNextFilledChunk();

results in "Chunk.h:23: warning: ‘Chunk* GetNextFilledChunk()’ declared ‘static’ but never defined"

What I find truly bizarre is that if I simply make GetNextFilledChunk() a plain old function, not a static member function, I can "friend" it and everybody is happy. But that seems silly - why should one be able to do something in a class from a non-class function that can't be done from a static member function?

So... How can Chunk's s GetNextFilledChunk() function access private member variables of a Chunk instance?

And if it can't be done, is it an inherent part of C++, or simply a bug in g++?

+5  A: 

You're defining your member function wrong. It should be defined like this:

Chunk * Chunk::GetNextFilledChunk()
{
    ...
}

That the definition happened to compile fine was due to a quirk with the language: class names get inserted within their own namespaces, so Chunk::Chunk is equivalent to Chunk, so you were defining a global function by accident.

Adam Rosenfield
+6  A: 

The problem is in your definition of GetNextFilledChunk. As written in the CPP file you have declared a non-member function which is preceeded by a badly formed label. It will not line up with the member function in the header.

The correct signature is as follows

Chunk*  
Chunk::GetNextFilledChunk() {
  ...
}
JaredPar
+18  A: 

This looks a little bizarre:

Chunk::
Chunk*  GetNextFilledChunk()
{

Is that a typo? Should it be:

Chunk* Chunk::GetNextFilledChunk()
{

? It looks like you're accidentally defining GetNextFilledChunk to be a plain function rather than a member of Chunk.

RichieHindle
Sometimes things are just so simple :)
Matthieu M.
Duh! <whacks palm on forehead>That fixed it. Thanks!
Bob Murphy
We've all been there
gatorfax
+2  A: 

Firstly, like the others have mentioned, the function definition is wrong. Also a friend function is not required nor do access specifiers matter here since you intend the function to be a part of the class and is obviously not taken so by the compiler due to the typos.

As for a straight answer to your question: How can a public static member function access private instance member variables?

It cannot; only non-static member functions can access both static and non-static variables and static member functions can only access static member variables. Reason: There is no object instantiation required to call a static function and hence there is no this pointer to a static member function and hence, in turn, no non-static member variables to access.

legends2k
Not so. Once I fixed the typo as suggested, the static member function was able to access the private member variables of Chunk instances, as long as it had a pointer to the Chunk.
Bob Murphy
Still you're accessing the non-static variables only via an object (ref./ptr) and not directly without a pointer. Try using m_ActualTextSize directly inside the static member function, without any reference or pointers. It won't compile.
legends2k
Well, yes, I knew that. The problem was really the typo.
Bob Murphy
A: 

I think singleton pattern fits very well for this. You can access any kind of member functions without worrying if you are accessing it from static functions or not...

VNarasimhaM