Passing an array of a structure to that structure's functions

I'm having problems with line 61, but let me tell you what is supposed to be happening:
I have a structure called 'member', and have created an array of this datatype called 'network' (line 36).
I have then allocated two elements to the first item in the array (memb in line 45 and category in line 58).
I am then passing the array (network) and the required record number (i) to a function (displaysinglerecord) defined as part of the structure (line 18+) for it to be displayed.

Now, line 61.
I originally had this line without the 'member::' bit, but got the error message that this function "was not declared in this scope".
This is, in itself confusing. The function was declared as part of the structure 'member', which main() does can see.
But I thought a simple solution to this error was to tell the program where displaysinglerecord was declared - as part of the structure 'member' - so I added the "member::" bit to it. I now get the error message "cannot call member function 'void member::displaysinglerecord(member*,int) without object"
I have tried adding the size of the array to the parameters (although I am telling the function which record in the array is required), but I get the same results.
In truth, I don't really know what sort of "object" it is expecting, but (based on the fact that, when the code in the function is just put in main() instead of the function call, it produces the result I expect) I suspect it is something to do with the parameters and is probably a case of me missing something blindingly obvious.
Any pointers greatly appreciated.
Thanks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <stdio.h>
	#include <stdlib.h>
	#include <time.h>
	#include <iostream>

using std::cout;
using std::endl;

struct member{
  int memb;
  int event;
  int ud;
  int uc;
  char category;
  int priority;

// put functions here
void displaysinglerecord(member network[], int r)
{
cout<<"member# : "<<network[r].memb<<endl;
//cout<<"event# : "<<network[r].event<<endl;
//cout<<"u/l distributor : "<<network[r].ud<<endl;
//cout<<"u/l customer : "<<network[r].uc<<endl;
cout<<"category : "<<network[r].category<<endl;
//cout<<"priority : "<<network[r].priority<<endl;	
}

}; // end of struc member definition

int main()
{
int randVal(int);
int i, r;
int f=0,b=0,e=0,d=0,n=0,t=0;
char c;
member network[2];

srand(time(NULL));

// this is where get-struct-record begins
// for testing just use one value initially
for(i=0; i<1; i++)
{
// allocate the membership number
network[i].memb = i+1;

// get random value and allocate the category
r=randVal(16);
switch(r) {
	case 0 : c='N'; break;
	case 15 : c='D'; break;
	case 14 : c='E'; break;
	case 13 : c='E'; break;
	case 12 : c='E'; break;
	case 11 : c='E'; break;
	default : c='B'; break;
		}
network[i].category = c;

// now use display single record function to display it ...
member::displaysinglerecord(network, i);

} // end of for-loop creating struct record
// this is where get-struct-record ends

} // end main()

int randVal(int n)
{
int m=rand() %n;
return m;
}




Last edited on
I now get the error message "cannot call member function 'void member::displaysinglerecord(member*,int) without object"
You can call the function without an object by making it static:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct member{
  int memb;
  int event;
  int ud;
  int uc;
  char category;
  int priority;

// put functions here
static void displaysinglerecord(member network[], int r) // Note: static
{
cout<<"member# : "<<network[r].memb<<endl;
//cout<<"event# : "<<network[r].event<<endl;
//cout<<"u/l distributor : "<<network[r].ud<<endl;
//cout<<"u/l customer : "<<network[r].uc<<endl;
cout<<"category : "<<network[r].category<<endl;
//cout<<"priority : "<<network[r].priority<<endl;	
}

}; // end of struc member definition 
But honestly, why is this function inside the class member at all? You may make it friend or move it outside the class.
You've made displaysinglerecord() a member of the member class. Looking at the parameters of that method, I assume the intention is for the method to operate on a single member object, yes?

If that's the case, then you don't need to pass in any parameters at all. You simply call the method on the member object upon which you want it to operate:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct member{
  //...
  void displaysinglerecord() 
  {
    // ...
  }
}; // end of struc member definition

int main()
{
  // ...
  for(i=0; i<1; i++)
  {
    // ...

    // now use display single record function to display it ...
    network[i].displaysinglerecord();
  }
}


EDIT: By the way, indentation really is your friend. Adopting a sensible indentation style will help you (and others) see the layout of your code more easily, and spot errors more quickly.
Last edited on
Thank you both for your responses.

My impression is that the second solution is probably the more elegant. From a quick search on static functions, I get the impression this would reduce the encapsulation (probably the wrong word) of the 'member' structure. Which, to answer coder's question, is why I put it inside the structure definition. My understanding is that when functions are only applicable to a structure, it is better practice to define them within that structure rather than elsewhere within the program. Is this not so?

As regards indentation, I agree, but my problem is that I tend to write (build up) my code on notepad and then just copy/paste it into the c++ compiler program when I think it is ready for testing. As such indentation is a manual exercise rather than being automatic like for code written directly into the compiler. At this point, the word "sensible" becomes the salient one - which is often missing from my final results! However, I take your point and will try to do better.

Thanks.
Is this not so?

Scott Meyers argues that non-friend non-members improve encapsulation.
Similarly, Herb Sutter does consider standalone functions a part of the interface of a class when they come with the class.

Besides, this case is a poster-boy for overloaded operator:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct member{
  //...
}; // end of struc member definition

std::ostream& operator<< ( std::ostream out, const member& rhs ) 
{
  // print members of rhs to out
  return out;
}

int main()
{
  // ...
  for(i=0; i<1; i++)
  {
    // ...
    std::cout << network[i];
  }
}

With a class (i.e. private members):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class member{
  //...
public:
  void display( std::ostream& ) const;
}; // end of class member definition

void member::display( std::ostream& out ) const
{
  // print members of this to out
}

std::ostream& operator<< ( std::ostream out, const member& rhs ) 
{
  rsh.display( out );
  return out;
}

Here the operator<< is just a convenience wrapper for display() that has access to privates.
You're welcome.

And, honestly, the best present you could give yourself is to use a more friendly editor. Even if you don't want to go the route of using an IDE on your own computer, something like the excellent Notepad++ is a plain-text editor that will do things like auto-indenting code, and give you context-sensitive colouring.

And even if you absolutely, positively have to indent everything manually yourself, you will still find it worth doing, for the improvement in readability it will give you.
Yes, that. One does not "copy/paste it into the c++ compiler program".
IDE is not a "compiler program". IDE has/uses a compiler.
Compiler reads files; compiles source into executable.

If you are copy-pasting, then you are copying from one editor to an another editor.
It should be possible to run the compiler on the files directly, without the IDE and copy-pasting.
Topic archived. No new replies allowed.