But I have to use a struct!

P

Pep

I have this massive legacy application to support and although it is
C++, it has been mostly written like a C application, making extensive
uses of structs instead of classes, which are recorded for persistence
in a database as a straight binary write.

So in order to supply a better way of handling a complex data field in
one of the structs, I have created another struct which is included
inside the original struct and things are working fine.

However my problem is that the new struct needs to have a member that
takes a parameter of the same struct and at that point C++ is
complaining.

The struct looks like this

typedef struct
{
private:
int field1;
int field2;
public:
setField1(int foo)
{
field1 = foo;
}

setField2(int foo)
{
field1 = foo;
}

setFields(myStruct& foo)
{
setField1(foo.field1);
setField2(foo.field2);
}
} myStruct;

However g++ complains that I am using a undeclared type in the
setFields method.

I have tried declaring it as setFields(struct myStruct& foo) and have
tried a forward declaration of struct myStruct before the struct
definition but none of these approaches work.

I do not want to use a void* ptr in the setFields method, is there any
way to do what I want to do?

TIA,
Pep.
 
K

kwikius

Pep wrote:
I do not want to use a void* ptr in the setFields method, is there any
way to do what I want to do?

Try changing to use the form:

struct myStruct
{
private:
int field1;
int field2;
public:
//(Also C++ needs return types for functions)
void setField1(int foo)
/////////////////
{
field1 = foo;
}


void setField2(int foo)
{
field1 = foo;
}


void setFields(myStruct& foo)
{
setField1(foo.field1);
setField2(foo.field2);
}
} ;

regards
Andy Little
 
A

amirkam1

typedef struct

If this is C++ code, you can write it like this (same as that of class
in C++)

struct MyStruct
{
public:
void function(MyStruct& xyz)
{

}
};
 
I

Ivan Vecerina

: However my problem is that the new struct needs to have a member that
: takes a parameter of the same struct and at that point C++ is
: complaining.
:
: The struct looks like this
:
: typedef struct
: {
: private:
: int field1;
: int field2;
: public:
: setField1(int foo)
: {
: field1 = foo;
: }
:
: setField2(int foo)
: {
: field1 = foo;
: }
:
: setFields(myStruct& foo)
: {
: setField1(foo.field1);
: setField2(foo.field2);
: }
: } myStruct;
:
: However g++ complains that I am using a undeclared type in the
: setFields method.
When using the "typedef struct" trick in C, you often
also need to give a name to the struct itself.
For example:
typedef struct Foo_tag {
//....
struct Foo_tag* next;
} Foo;
Or use a the following correct forward-declaration:
typedef struct Foo_tag Foo;
struct Foo_tag {
//....
Foo* next;
};

But since you are using C++-only constructs anyway,
why don't you just get rid of the "typedef struct"
trick, which is only useful in C ?

Write:
struct myStruct { .... setFields(myStruct& foo) ... };


hth -Ivan
 
A

Alan Johnson

Pep said:
I have this massive legacy application to support and although it is
C++, it has been mostly written like a C application, making extensive
uses of structs instead of classes, which are recorded for persistence
in a database as a straight binary write.

So in order to supply a better way of handling a complex data field in
one of the structs, I have created another struct which is included
inside the original struct and things are working fine.

Be careful that you do not inadvertently make your struct into a non-POD
type, as that could break the "binary write" to your database. In
particular, avoid adding a copy assignment operator or a destructor.
 
P

Pep

kwikius said:
Pep wrote:


Try changing to use the form:

struct myStruct
{
private:
int field1;
int field2;
public:
//(Also C++ needs return types for functions)
void setField1(int foo)
/////////////////
{
field1 = foo;
}


void setField2(int foo)
{
field1 = foo;
}


void setFields(myStruct& foo)
{
setField1(foo.field1);
setField2(foo.field2);
}
} ;

regards
Andy Little

Yep I missed the function type when I created the test class to show
the problem I am trying to resolve :(

As for the struct definition, of course it works fine when typedef is
removed. It's one of those obvious things that you miss when you have
to deal with such badly written code. Legacy is bad enough but gets
much worse when the > 250,000 lines of code are badly written by a non
C++/C developer that used a how to code in 30 days book. Dotcom has a
lot to answer for :(
 
P

Pep

If this is C++ code, you can write it like this (same as that of class
in C++)

struct MyStruct
{
public:
void function(MyStruct& xyz)
{

}
};

Yep, removing the typedef worked fine, something I should have seen
myself but it's a case of "can't see the wood for the trees" ;)

Thanks,
Pep.
 
P

Pep

Ivan said:
: However my problem is that the new struct needs to have a member that
: takes a parameter of the same struct and at that point C++ is
: complaining.
:
: The struct looks like this
:
: typedef struct
: {
: private:
: int field1;
: int field2;
: public:
: setField1(int foo)
: {
: field1 = foo;
: }
:
: setField2(int foo)
: {
: field1 = foo;
: }
:
: setFields(myStruct& foo)
: {
: setField1(foo.field1);
: setField2(foo.field2);
: }
: } myStruct;
:
: However g++ complains that I am using a undeclared type in the
: setFields method.
When using the "typedef struct" trick in C, you often
also need to give a name to the struct itself.
For example:
typedef struct Foo_tag {
//....
struct Foo_tag* next;
} Foo;
Or use a the following correct forward-declaration:
typedef struct Foo_tag Foo;
struct Foo_tag {
//....
Foo* next;
};

But since you are using C++-only constructs anyway,
why don't you just get rid of the "typedef struct"
trick, which is only useful in C ?

Write:
struct myStruct { .... setFields(myStruct& foo) ... };


hth -Ivan

Thanks Ivan, of course removing the typedef works fine :)

Guess I need a holiday form this code and then come back and start all
over again. Would be nice to work on a clean code development just for
once.

Cheers,
Pep.
 
P

Pep

Alan said:
Be careful that you do not inadvertently make your struct into a non-POD
type, as that could break the "binary write" to your database. In
particular, avoid adding a copy assignment operator or a destructor.

Good point. I am not adding any ctors or dtors so that should resolve
the issue. It's basically a struct with fields and setter/getter
methods.

Cheers,
Pep.
 
J

Jerry Coffin

[ ... ]
typedef struct
{
private:
int field1;
int field2;
public:
setField1(int foo)
{
field1 = foo;
}

setField2(int foo)
{
field1 = foo;
}

setFields(myStruct& foo)
{
setField1(foo.field1);
setField2(foo.field2);
}
} myStruct;

Your original question has been answered, but it leaves a much more
important one: what are you really trying to accomplish with this?
Right now, what you have is still almost equivalent to a struct in
which field1 and field2 are public. The only difference is that you
can't read their values. Right now, since they're private, and you
haven't declared any friends, and nothing in the struct uses their
values -- so you can set the values, but never make any use of them.

This looks a lot like a classic case of adding manipulator functions
that are intended to "help encapsulation" (or something on that
order), but so far, really accomplish nothing positive at all. Rather
the contrary, what you've got right now will make your code uglier
and harder to read, without providing anything useful in return.

Simply changing 'x.field1 = 1' to 'x.setField1(1)' isn't a good
thing. To accomplish something useful, you need to provide some more
intelligence. One of the basic ideas of any function is that code
that uses that function should be able to operate at a higher level
of abstraction than the code internal to the function. In this case,
you're doing more or less the reverse -- internally the function uses
a high-level assignment abstraction, but code that uses it is more
like a warped version of assembly language.

My advice would be to step back and explain to us what this struct is
really supposed to accomplish. If it really makes sense for the
client code to use functions like setField1, setField2 and setFields,
then you should probably just make field1 and field2 public and be
done with it. If there's a good reason for them to be internal and
protected, then you should implement those reasons into the code.
 

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

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top