difficulties translating a random number gnerator to a header file and classes to call from main program

I wrote a simple random number generator that outputs from 1 to 4, but I can't seem to wrap my head around how to put it in a class header file

dice.h
1
2
3
4
5
6
7
8
9
#ifndef RESOURCES_H
#define RESOURCES_H

class Die{
public:
	int roll();
};

#endif 

dice.cpp
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "dice.h"

Die::roll()
{
	srand(time(0));
	roll()=rand()%4+1;
	std::cout << roll << std::endl;
}

main.cpp
1
2
3
4
5
6
7
8
9
#include <iostream>
#include "dice.h"
using namespace std;

int main()
{
	Die::roll
	return 0;
}

terminal output and errors
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
main.cpp: In function ‘int main()’:
main.cpp:7:7: error: invalid use of non-static member function ‘int Die::roll()’
    7 |  Die::roll
      |       ^~~~
dice.cpp:6:11: error: ISO C++ forbids declaration of ‘roll’ with no type [-fpermissive]
    6 | Die::roll()
      |           ^
dice.cpp: In member function ‘int Die::roll()’:
dice.cpp:9:18: error: lvalue required as left operand of assignment
    9 |  roll()=rand()%4+1;
      |                  ^
dice.cpp:10:12: error: invalid use of non-static member function ‘int Die::roll()’
   10 |  std::cout << roll << std::endl;
      |  ~~~~~~~~~~^~~~~~~
dice.cpp:6:1: note: declared here
    6 | Die::roll()
      | ^~~
dice.cpp:11:1: warning: no return statement in function returning non-void [-Wreturn-type]
   11 | }
      | ^

Note: I wrote this after learning about classes to try and wrap my head around them, clearly I have a lot of learning left to do
Last edited on
1. First of all, there are better random number generators out there. You should learn about them. But since you are using rand...

2. The srand (random number seed function) should only be called 1 time in the entire program. Call it in main() or have a static function in your Die class that calls it, and call that function in main. DO NOT call it every time you call roll.

3. Die::roll() is supposed to return an int. You do not return anything.

4. Your definition of Die::roll() (line 6 of dice.cpp) doe not provide a return type. It MUST match the declaration from dice.h

5. Line 9 is nonsensical. You want to assign the result of rand()%4+1 to a variable. Instead you are trying to assign it to a recursive call to roll() (which makes no sense). Declare a variable here: int result = rand() % 4 + 1; and then do something with the result. (Hint: consider comment #3)

6. It is better to have functions do 1 thing only. So, I would recommend having roll() return the value (as declared in the header), and let the caller (in this case main()) print it or whatever.

7. In order to call roll(), you need to declare an object or type Die, and call roll() on that object:
1
2
Die d;
int result = d.roll();


8. Generally file names reflect the classes that they define. So, better names for your files would be Die.h and Die.cpp.
Last edited on
So I'm playing around with your suggestions (I'm a total noob to programming, sorry), and while I am learning I'm getting new errors I don't understand.
I changed all the files. main.cpp no longer gives an error, but dice.h gives a lot with srand.
dice.h
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef RESOURCES_H
#define RESOURCES_H
#include <cstdlib>
#include <ctime>

class Die{
public:
	srand(time(0));
	int roll();
};

#endif 

dice.cpp
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "dice.h"

int Die::roll()
{
	int result = rand()%4+1;
	return result;
}

main.cpp
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include "dice.h"
using namespace std;

int main()
{
	Die d;
	int result = d.roll();
	cout << result << endl;
	return 0;
}

at the end I'll change the file names.
Errors remaining:
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
In file included from main.cpp:2:
dice.h:8:8: error: ‘time’ is not a type
    8 |  srand(time(0));
      |        ^~~~
dice.h:8:13: error: expected ‘)’ before numeric constant
    8 |  srand(time(0));
      |            ~^
      |             )
dice.h:8:13: error: expected ‘)’ before numeric constant
    8 |  srand(time(0));
      |       ~     ^
      |             )
dice.h:8:13: error: ISO C++ forbids declaration of ‘srand’ with no type [-fpermissive]
dice.h:8:12: error: expected ‘;’ at end of member declaration
    8 |  srand(time(0));
      |            ^
      |             ;
dice.h:8:13: error: expected unqualified-id before numeric constant
    8 |  srand(time(0));
      |             ^
In file included from dice.cpp:4:
dice.h:8:8: error: ‘time’ is not a type
    8 |  srand(time(0));
      |        ^~~~
dice.h:8:13: error: expected ‘)’ before numeric constant
    8 |  srand(time(0));
      |            ~^
      |             )
dice.h:8:13: error: expected ‘)’ before numeric constant
    8 |  srand(time(0));
      |       ~     ^
      |             )
dice.h:8:13: error: ISO C++ forbids declaration of ‘srand’ with no type [-fpermissive]
dice.h:8:12: error: expected ‘;’ at end of member declaration
    8 |  srand(time(0));
      |            ^
      |             ;
dice.h:8:13: error: expected unqualified-id before numeric constant
    8 |  srand(time(0));
      |             ^
I moved srand to main.cpp and now it's working perfectly, thanks for the help!
For a C++ approach using <random> and <chrono> a simplistic [and work-in-progress messy] header-only approach:

(random_toolkit.hpp)
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
73
74
75
76
77
78
79
80
81
82
83
84
/* A simple toolkit to help beginners using <random> library an easier task */

// shamelessly stolen and adapted from a C++ working paper: WG21 N3551
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3551.pdf

#ifndef __RANDOM_TOOLKIT_HPP__
#define __RANDOM_TOOLKIT_HPP__

#include <chrono>
#include <random>
#include <stdexcept>

namespace rtk
{
   static bool seeded { false };

   inline std::default_random_engine& urng()
   {
      static std::default_random_engine URNG { };

      return URNG;
   }

   inline void srand(bool FORCE_SEED = false)
   {
      static const std::seed_seq::result_type seeds[] { std::random_device {}(),
                                                        std::seed_seq::result_type(std::chrono::system_clock::now().time_since_epoch().count()) };
      static std::seed_seq sseq(std::begin(seeds), std::end(seeds));

      // static unsigned seed = static_cast<unsigned> (std::chrono::system_clock::now().time_since_epoch().count());

      // the URNG can't be reseeded unless forced
      if (!seeded || FORCE_SEED)
      {
         urng().seed(sseq);

         seeded = true;
      }
   }

   inline void srand(unsigned seed, bool FORCE_SEED = false)
   {
      // the URNG can't be reseeded unless forced
      if (!seeded || FORCE_SEED)
      {
         urng().seed(seed);

         seeded = true;
      }
   }

   // two function overloads to obtain uniform distribution ints and doubles
   inline int rand(int from, int to)
   {
      static std::uniform_int_distribution<> dist { };

      if (from > to) { throw std::invalid_argument("bad int params"); }

      return dist(urng(), decltype(dist)::param_type { from, to });
   }

   inline double rand(double from, double to)
   {
      static std::uniform_real_distribution<> dist { };

      if (from > to) { throw std::invalid_argument("bad double params"); }

      return dist(urng(), decltype(dist)::param_type { from, to });
   }

   // function for rolling dice, and checking if the # of pips is nonstandard
   inline int roll_die(int pips)
   {
      //check to see if the number of die pips is less than 2
      if (pips < 2)
      {
         return 0;
      }

      return rand(1, pips);
   }
}

#endif 
Registered users can post here. Sign in or register to post.