Problem with class forward declaration

M

Martin Eisenberg

Hi!

I have a header with two classes, WidthLogger and Hyst. WidthLogger
is declared first; its ctor takes a Hyst reference. Hyst declares
WidthLogger a friend. Hyst constructs a WidthLogger member, giving
itself as parameter, and calls its log() method in various places.
WidthLogger::log() then uses the reference to note down the values of
some Hyst members.

Except that I don't get that far because VC6 is bitchin', I hope
someone can explain why. Here is the complete beginning of said
header, just in case the actual problem is not where the first
message occurs:

#ifndef __hyst__
#define __hyst__

#include <cmath>
#include <mCmath.h>

//-------

// see Hyst: tick(), setWidth()
#define DEBUG_SHAPE
//#define DEBUG_STAGES

//------------------------------------------------

#define MAX_STAGES 6
#define MAX_SLEW 0.98f
#define NUM_SHAPES 2
#define SHAPE1_DEGREE 3
#define SHAPE1_MAX_WIDTH 0.6f
#define EPSILON 0.000000001f // ~ 2^-30

//------------------------------------------------

#ifdef DEBUG_SHAPE

#include <fstream>

class Hyst;

class WidthLogger {
public:
WidthLogger(const Hyst& h)
: h_(h), f_("width.log"), prevWidth_(-1.f), entries_(0)
{}

void log(void)
{
if(h_.width_ ...

(end of excerpt)

On the last line, the compiler gives:

hyst5.h(49) : error C2027: use of undefined type 'Hyst'
hyst5.h(34) : see declaration of 'Hyst'

I figured I might not need to declare Hyst, since its definition
immediately follows WidthLogger. But commenting out the declaration
produced

hyst5.h(38) : error C2629: unexpected 'class WidthLogger ('

which I understand even less, since the incriminating character
sequence does not occur anywhere! Of course, the follow-on errors
aren't illuminating either. Again, I'd be most thankful if anyone
could make the issue clear to me.


Martin
 
R

Ron Natalie

Martin Eisenberg said:
#ifndef __hyst__
#define __hyst__

Illegal symbol for you to be using.

hyst5.h(49) : error C2027: use of undefined type 'Hyst'
hyst5.h(34) : see declaration of 'Hyst'

I figured I might not need to declare Hyst, since its definition
immediately follows WidthLogger. But commenting out the declaration
produced

hyst5.h(38) : error C2629: unexpected 'class WidthLogger ('

which I understand even less, since the incriminating character
sequence does not occur anywhere! Of course, the follow-on errors
aren't illuminating either. Again, I'd be most thankful if anyone
could make the issue clear to me.

Start by reading this.

http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-38.11

You need to define both classes without making any reference to the members
of the other. That is, you need to move the implementation of your function log
until after Hyst is fully defined.
..
class Hyst; // forward decl
class WidthLogger {
public:
WIdthLogger(const Hyst&);
void log();
};
clsas Hyst {
// declaration of hyst's members.
};

WidthLogger::WIdthLogger(const Hyst& h) : h_(h), f_("widht.log), ... { }
void WidthLogger::log() { if(h_.width_ ...
 
V

Victor Bazarov

Martin Eisenberg said:
I have a header with two classes, WidthLogger and Hyst. WidthLogger
is declared first; its ctor takes a Hyst reference. Hyst declares
WidthLogger a friend. Hyst constructs a WidthLogger member, giving
itself as parameter, and calls its log() method in various places.
WidthLogger::log() then uses the reference to note down the values of
some Hyst members.

Except that I don't get that far because VC6 is bitchin', I hope
someone can explain why. Here is the complete beginning of said
header, just in case the actual problem is not where the first
message occurs:

#ifndef __hyst__
#define __hyst__

Use of double underscores is reserved by the implementation. Try to
get rid of this habit. Nothing wrong with INCLUDED_HYST name.
#include <cmath>
#include <mCmath.h>

//-------

// see Hyst: tick(), setWidth()
#define DEBUG_SHAPE
//#define DEBUG_STAGES

//------------------------------------------------

#define MAX_STAGES 6
#define MAX_SLEW 0.98f
#define NUM_SHAPES 2
#define SHAPE1_DEGREE 3
#define SHAPE1_MAX_WIDTH 0.6f
#define EPSILON 0.000000001f // ~ 2^-30

//------------------------------------------------

#ifdef DEBUG_SHAPE

#include <fstream>

class Hyst;

class WidthLogger {
public:
WidthLogger(const Hyst& h)
: h_(h), f_("width.log"), prevWidth_(-1.f), entries_(0)
{}

void log(void)
{
if(h_.width_ ...

In order to use the members of an object of class 'Hyst', the
compiler has to know the _layout_ of the class. A forward
declaration is certainly not enough for that.
(end of excerpt)

On the last line, the compiler gives:

hyst5.h(49) : error C2027: use of undefined type 'Hyst'
hyst5.h(34) : see declaration of 'Hyst'
Sure.


I figured I might not need to declare Hyst, since its definition
immediately follows WidthLogger. But commenting out the declaration
produced

hyst5.h(38) : error C2629: unexpected 'class WidthLogger ('

which I understand even less, since the incriminating character
sequence does not occur anywhere! Of course, the follow-on errors
aren't illuminating either. Again, I'd be most thankful if anyone
could make the issue clear to me.

Pull the 'void log()' definition out of the 'WidthLogger' class
and place it _after_ the 'Hyst' class definition, declaring it
'inline':

class WidthLogger {
...
void log();
};

class Hyst {
...
};

inline void WidthLogger::log() {
...
}

[that is, if you _have_ to have them in the header]

Victor
 
M

Martin Eisenberg

Thank you, Victor and Ron, for replying. I guess I should have
consulted the FAQ in the first place... In hindsight, the problem is
kind of obvious.

Victor said:
Use of double underscores is reserved by the implementation.
Try to get rid of this habit. Nothing wrong with INCLUDED_HYST
name.

Well, I haven't acquired it yet. I just didn't realize that that rule
applies to preprocessor symbols just like to other code entities.
[that is, if you _have_ to have them in the header]

No, I don't have to. My plan was to keep everything in one place
until the thing works, but I'll just go ahead and rip the definitions
out now.


Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top