Referencing an instance of a class created in main from another class module

Worldtraveler58

I’m working on a variant of poker which requires two decks. For statistical reasons it’s important that when shuffling the two decks a common random number generator be used. For testing I have a small main where I create an instance of the random number generator and two instances of the deck. I reference to the instance “Random” in classDeck with the statement “extern classRNG Random.”

Everything compiles OK, but I get the linker error “Deck.obj : error LNK2001: unresolved external symbol "class classRNG Random" (?Random@@3VclassRNG@@A).” If I create the instance Random in classDeck instead of in main everything compiles and links OK, but of course that would create a separate random number generator for each deck.

There is clearly something I’m overlooking.

It's a lot of code to go through, but I think the error is being created by the function "Shuffle" in Deck.cpp, near the end of Deck.cpp. That's were I have the statement "extern classRNG Random." Commenting out the line "RawDeck[i].SortParam = Random.RNGGet()" eliminates the error.

Here’s the code for RNG.h:

#ifndef RNG_H 
#define RNG_H 

class classRNG
{
private:
    static unsigned long long Seed;

public:   
    classRNG();   // Default constructor;
    classRNG(unsigned long long ullSeed); // Constructor with initial seed
    unsigned long long RNGGet();  //Get a random number
};
#endif

RNG.cpp:

#include <iostream>
#include <vector>
#include <string>
#include <math.h>
#include <stdbool.h>
#include "RNG.h"

using namespace std;

const unsigned long long T1 = 60LL, T2 = 59LL;

classRNG::classRNG()   // Default constructor
{
int i;

Seed = 3;

for (i=0; i<7*T1; i++)      //Step thru some numbers to stabilize
{
    RNGGet();
}
};

classRNG::classRNG(unsigned long long ullSeed) // Constructor with initial seed
{
const unsigned long long Mask1 = powl(2LL,T1);
const unsigned long long Mask = Mask1 - 2LL;

int i;

Seed = ullSeed % Mask;
for (i=0; i<7*T1; i++)      //Step over trivial numbers
{
    RNGGet();
}
};

// This method is used to obtain a random number.  It returns an unsigned Long Long.
unsigned long long classRNG::RNGGet()
{
const long long Test1 = powl(2LL, T1-1LL);
const long long Test2 = powl(2LL, T2-1LL);
const unsigned long long Mask1 = powl(2LL,T1);
const unsigned long long Mask = Mask1 - 2LL;
const unsigned long long Taps = Test1 | Test2;
const unsigned long long Scram = 0x693474786E579bd % Mask;

unsigned long long Test;

Test = Seed & Taps;
Seed = (Seed << 1) & Mask;
if (Test == Test1 | Test == Test2){
    Seed = Seed | 1LL;
}
return Seed * Scram;
};

unsigned long long classRNG::Seed = 3;

Deck.h:

#ifndef DECK_H
#define DECK_H

#include "struct_defs.h"

class classDeck
{
private:
    static int NextCard;    // Pointer to next card in the deck 
    static bool Ready;  // Indicates that deck is not dirty
    static structSortCard RawDeck[53];  // Stores the raw card value (1-52) with a sort parameter

    bool SortDeck(int Plow, int Phi);   // Used in Shuffle
    void SwapCards(int P1, int P2);     // Used in SortDeck

public:
    classDeck();  //Constructor;
    bool InitializeDeck();
    bool Shuffle();
    structCardDef GetCard();
    bool DeckReady ();
};
#endif

Deck.cpp:

#include <iostream>
#include <vector>
#include <string>
#include <math.h>
#include <stdbool.h>
#include "RNG.h"
#include "struct_defs.h"    // Data structures
#include "Deck.h"

using namespace std;

/* 
This type manages the card deck.  No data are directly exposed.  It provides the following methods:
- InitializeDeck.   Restores deck to unsorted state. (Probably never use this)
- Shuffle.          Returns True when complete.
- GetCard.          Returns the next card as Class classCardDef.
- DeckReady.        Returns True if the deck is shuffled and not dirty. 
*/

int classDeck::NextCard = 1;
bool classDeck::Ready = false;
structSortCard classDeck::RawDeck[] = {0};

classDeck::classDeck()  //Constructor
{
InitializeDeck();
};


bool classDeck::SortDeck(int Plow, int Phi)
{
int Pivot, P1, P2, P3, i;

Ready = false;

// Check for trivial cases
if ((Phi - Plow) < 2)   // Nothing to sort
{
    return true;
}
if (((Phi - Plow) == 2) && RawDeck[Plow].SortParam > RawDeck[Phi].SortParam)    // Only two - easy peasy
{
    SwapCards(Phi, Plow);
    return true;
}

// Set Pivot to last element
Pivot = Phi;
P3 = 0;

// Search for an element larger than the pivot, and set P1 to that
for (P1 = Plow; P1 < Pivot; P1++)
{
    if(RawDeck[P1].SortParam > RawDeck[Pivot].SortParam)    // Found a large number
    {
        // Search from P1+1 to Pivot-1 to find an element smaller than the pivot and set P2 to that
    for (P2 = P1+1; P2 < Pivot; P2++)
        {
            if(RawDeck[P2].SortParam < RawDeck[Pivot].SortParam)    // Found a small number
            {
                // Swap elements at P1 & P2
                SwapCards(P1, P2);
                P3 = P1;    // Remember leftmost large card
                break;
            }
        }
        if (P2 >= Pivot)   // Reached the pivot without finding another small card
        {
            break;
        }
    }
}

// Move Pivot to P3
if (P3 > 0) // There's at least one large card
{
    SwapCards(P3, Pivot);  // The Pivot is now at P3
}

// Split into two parts, and iterate any part with more than one element
Ready = SortDeck(Plow, P3 - 1) && SortDeck(P3 + 1, Phi);
return Ready;
};


void classDeck::SwapCards(int P1, int P2)
{
structSortCard Temp;

Temp.Value  = RawDeck[P1].Value;
Temp.SortParam = RawDeck[P1].SortParam;

RawDeck[P1].Value = RawDeck[P2].Value;
RawDeck[P1].SortParam = RawDeck[P2].SortParam;

RawDeck[P2].Value = Temp.Value;
RawDeck[P2].SortParam = Temp.SortParam;
};



bool classDeck::InitializeDeck()
{
int i;

Ready = false;
for (i = 1; i <= 52; i++)
{
    RawDeck[i].Value = i;
}
Ready = Shuffle();
return Ready;
};


bool classDeck::Shuffle()
{
int i;
extern classRNG Random;

Ready = false;
for (i = 1; i <= 52;i++)
{
    RawDeck[i].SortParam = Random.RNGGet();
}

// Sort the deck
Ready = SortDeck(1, 52);
return Ready;
};


structCardDef classDeck::GetCard()
{
structCardDef NewCard;
int Card;

Ready = false;
Card = RawDeck[NextCard++].Value;
NewCard.Card = Card % 13 + 1;
NewCard.Suit = Card / 13 + 1;
return NewCard;
};


bool classDeck::DeckReady ()
{
return Ready;
};

And finally, main.cpp

#include <iostream>
#include <vector>
#include <string>
#include <math.h>
#include <stdbool.h>
#include "RNG.h"
#include "struct_defs.h"
#include "Deck.h"

using namespace std;

int main()
{
unsigned long long X;
classRNG Random;    // Create an instance of classRNG
X = Random.RNGGet();

// Create two decks
classDeck Deck[2];

The structure "structSortCard" is defined in "struct_defs.h" as:

struct structSortCard
{
public:
    int Value;
    unsigned long long SortParam;
};

I've tried a lot of things to no avail.

Oliver Dain

classRNG Random is local to main - it's not a global variable so isn't visible in your extern call in classDeck::Shuffle. Using an extern to share a variable is a bit odd - why not either have Shuffle take a classRNG* parameter so you can pass the same classRNG to each instance (or you could pass it in the constructor if you prefer). Alternatively you could also make the RNG a static member of classDeck so the deck will be in charge of constructing exactly one classRNG that is shared amongst all instances.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Referencing db context class from another class

Python: class instance created in module function not visible from other modules

Accessing an instance of a class defined in main in another class

Referencing instance variables from within abstract class

Pass class object instance as parameter to another class object instance from main()

C#: pass an instance of a class from one module to another

Referencing a Function From Another Class in Kivy

Calling a class from another class with main method

Using an object from main class in another class

Access main class from another PHP class

One instance attribute referencing another, with updates after class instantiation

create an instance of one class from another class

Create instance of a class in the hilt in the another module

Referencing a class variable from another class via a method

Referencing class instance through lists

Check class instance passed to another module is of type class

Python - instance of a class from another file accessing a var from the main script

Call from a main of one class, a main method of another class

How to mock class instance exported from file with another class instance

Can an instance from one class change variables in an instance of another class?

python class instance method call from another class instance

Update current instance of Window from another class, rather than the newly created C# WPF

where is instance of class created

Python - import instance of class from module

How to access class module from object instance?

JavaFx: how to reference main Controller class instance from CustomComponentController class?

How to tell if an instance of a parent class was created from an instance of a particular child

How to close main window from another class?

Using methods from another class in the main?