-1

I am trying to break the following code up into separate header and implementation files in C++:

class randomInteger {
  public:
       unsigned int operator () (unsigned int);
} randomizer;
unsigned int randomInteger::operator () (unsigned int max)
{
  // rand return random integer
  // convert to unsigned to make positive
  // take remainder to put in range
  unsigned int rval = rand();
  return rval % max;
}
unsigned int randBetween(int low, int high) {
  return low + randomizer(high - low);
}

Here is what I have split apart: RandomInteger.h

#ifndef __EventSimulation__RandomInteger__
#define __EventSimulation__RandomInteger__

#include <iostream>

class RandomInteger {
public:
    // MEMBERS
    unsigned int operator () (unsigned int);
    unsigned int randBetween(int low, int high);
} randomizer;

#endif

RandomInteger.cpp

#include "RandomInteger.h"

unsigned int RandomInteger::operator () (unsigned int max) {
    // rand return random integer
    // convert to unsigned to make positive
    // take remainder to put in range
    unsigned int rval = rand();
    return rval % max;
}

unsigned int RandomInteger::randBetween(int low, int high) {
    return low + RandomInteger(high - low);
}

When I use the class in my main method for testing and try running the program I get an error " linker command failed with exit code 1 (use -v to see invocation) " using Xcode.

Here is my simple main method:

int main(int argc, const char * argv[])
{

    // Test Randomized
    // Create a random number between 2 and 4
    int randomBeer = randomizer.randBetween(2, 4);

    // Switch to print beer
    cout << "BeerType: " << randomBeer << endl;
}

Here is a screen shot of the error: enter image description here

Matt
  • 879
  • 9
  • 29

2 Answers2

1

Two notes here:

  1. In RandomInteger.h file you define a randomizer variable and I believe you need to do this in source file;
  2. By writing RandomInteger(high - low); I think you want to call operator () (unsigned int) but instead you're trying to create an object like RandomInteger::RandomInteger(int). I don't think you have such constructor. Otherwise randomizer object won't be created (using default one without parameters).
0

In the first, unsplit version, you define a class and an instance of the class at the same time. The class has a data member and a single method. You then define a simple function, randBetween, that uses that instance.

When you broke it up, you still create a global instance, randomizer, but this time you made randBetween a method of class RandomInteger. When you migrated randBetween, though, you try to invoke a constructor, RandomInteger(int), which you never defined. (It could also be trying to look for a typecast operator, but not operator().)

Because you're creating that instance in every module in which you include RandomInteger.h, you're getting the duplicate symbol shown in your screenshot.

I'm not entirely sure what you're trying to accomplish here, so suggesting code that will "work" would require a number of assumptions. I don't see the need for a class here, as you seem to be doing nothing more than making a class to contain a couple of functions, rather than having an object that you'll want to instantiate more than once.

I should also note here that using the % operator, as you're doing, will give you unpredictable results, but not statistically random results; the distribution will be poor and predictable. Consider the method used in section 13.16 of the C Programming FAQ, or some of the more complex answers at this StackOverflow question.

Community
  • 1
  • 1
Joe Sewell
  • 306
  • 1
  • 11