In the code sample below, class Die is just a base class that AttackDie inherits. When AttackDie is instantiated, it needs data stored in an instance of class StatSys and an integer value. As a result, the constructor for AttackDie has been designed to take an instance of StatSys and a integer as inputs. However, the compiler is throwing a C2511 error on the line containing AttackDie::AttackDie(StatSys * LocalSystem, int Type)
The error is as follows:
AttackDie::AttackDie(StatSys *,int)': overloaded member function not found in 'AttackDie
I don't understand why this error is showing up. I've checked the header and source. The declaration and implementation interfaces both seem to match. Could someone direct me to the problem?
Code Samples
Dice.cpp
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <Dice.h>
#include <StatisticsSystem.h>
using namespace std;
AttackDie::AttackDie(StatSys * LocalSystem, int Type)
{
DataIntegrity = true;
if (Type > -1)
{
switch (Type)
{
case 0:
DieType = "Red";
DieClass = "Damage";
break;
case 1:
DieType = "Green";
DieClass = "Balanced";
break;
case 2:
DieType = "Blue";
DieClass = "Accuracy";
break;
case 3:
DieType = "Yellow";
DieClass = "Surge";
break;
default:
cout << "Unrecognized TypeNum value (>). Initialization of key AttackDie variables failed./n";
DieType = "Error";
DieClass = "Error";
DataIntegrity = false;
}
}
else
{
cout << "Unrecognized TypeNum value (<). Initialization of key AttackDie variables failed./n";
DieType = "Error";
DieClass = "Error";
DataIntegrity = false;
}
if (DataIntegrity)
{
const int GROUP_SIZE = 3;
int Iterator = 0;
int Test[3];
bool CSVDataValid = true;
for (int OuterCounter = 0; OuterCounter <= LocalSystem->NUM_OF_SIDES - 1; OuterCounter++)
{
Test[0] = LocalSystem->AccessCSVData(Type, Iterator);
Test[1] = LocalSystem->AccessCSVData(Type, Iterator + 1);
Test[2] = LocalSystem->AccessCSVData(Type, Iterator + 2);
Iterator += GROUP_SIZE;
if (Test[0] <= -1 || Test[1] <= -1 || Test[2] <= -1)
{
CSVDataValid = false;
}
else
{
Sides[OuterCounter].Damage = Test[0];
Sides[OuterCounter].Surges = Test[1];
Sides[OuterCounter].Accuracy = Test[2];
}
}
if (!CSVDataValid)
{
cout << "Side specific parameters were not set. CSV data not valid.";
DataIntegrity = false;
}
else
{
Total = { 0, 0, 0 };
for (int SideCounter = 0; SideCounter <= 5; SideCounter++)
{
Total.Damage += Sides[SideCounter].Damage;
Total.Surges += Sides[SideCounter].Surges;
Total.Accuracy += Sides[SideCounter].Accuracy;
}
Averages.Damage = Total.Damage / LocalSystem->NUM_OF_SIDES;
Averages.Surges = Total.Surges / LocalSystem->NUM_OF_SIDES;
Averages.Accuracy = Total.Accuracy / LocalSystem->NUM_OF_SIDES;
}
}
}
Dice.h
#pragma once
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <cmath>
using namespace std;
struct AttackStatAverages
{
double Damage;
double Surges;
double Accuracy;
};
struct DefenseStatAverages
{
double Blocks;
double Evades;
int Dodges;
};
class Die
{
public:
string GetDieType();
string GetDieClass();
protected:
string DieType;
string DieClass;
bool DataIntegrity;
};
class AttackDie : public Die
{
public:
AttackDie(StatSys * LocalSystem, int Type);
int GetSides(int SideNum, int Parameter);
double GetAverages(int Parameter);
int GetTotal(int Parameter);
~AttackDie();
private:
AttackStats Sides[6];
AttackStatAverages Averages;
AttackStats Total;
};
StatisticsSystem.h
#pragma once
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <cmath>
#include <Dice.h>
#include <vector>
using namespace std;
struct DicePackage
{
int Mode;
int Quantity;
int NumberOfPossibilities;
bool Error;
AttackDie* AttackDice[4];
DefenseDie* DefenseDice[3];
};
class StatSys
{
friend class AttackDie;
friend class DefenseDie;
public:
StatSys();
~StatSys();
const double VERSION = 0.1;
int AccessCSVData(int Row, int Column);
private:
static const int MAX_NUM_OF_DICE = 4;
const int METHOD_ERROR_SIZE = 10;
const int NUM_OF_SIDES = 6;
const int GROUP_SIZE = 3;
const int DAMAGE = 0;
const int SURGES = 1;
const int ACCURACY = 2;
const int BLOCKS = 0;
const int EVADES = 1;
const int DODGE = 2;
const int ITERATIONS = 3;
DicePackage DiceSet;
bool CSVDataState;
bool ErrorDataState;
int CSVData[6][18];
vector<string> Errors;
vector<string> ErrorDescriptions;
int StringToInt(string Value);
void LoadCSV();
#include <Dice.h>
#include <StatisticsSystem.h>
should be
#include "Dice.h"
#include "StatisticsSystem.h"
<> is primarily for system headers
"" are for header files in the same directory
Looks like user4581301 was correct. Adding #include <StatisticsSystem.h> to Dice.h fixed the issue since Dice.h does in fact need data from that header.
Related
I define a ThreadPoolclass, and it has a memeber: std::array<Worker, ThreadNum> Workerlist.
The code is as follows:
#ifndef THREADPOOL_H
#define THREADPOOL_H
#include <pthread.h>
#include <memory>
#include "Worker.h"
#include <vector>
#include <array>
const int MAX_THREAD_NUM = 16;
class ThreadPool
{
private:
const unsigned int ThreadNum;
std::shared_ptr<EventLoop> MainLoop;
std::array<std::shared_ptr<Worker>, ThreadNum> WorkerList;
std::array<std::shared_ptr<EventLoop>, ThreadNum> EventLoopList;
unsigned int NextLoopIndex;
public:
ThreadPool(std::shared_ptr<EventLoop> loop, int threadNum = 12);
~ThreadPool();
void RunThreadPool();
std::shared_ptr<EventLoop> GetNextEventLoop();
}
#endif
ThreadPool.cpp
ThreadPool::ThreadPool(std::shared_ptr<EventLoop> loop, int threadNum): MainLoop(loop), ThreadNum(threadNum), NextLoopIndex(0)
{
if (ThreadNum<=0 || ThreadNum> MAX_THREADS)
{
LOG << "The num of threads is out of range.\n";
}
}
ThreadPool::~ThreadPool() {}
void ThreadPool::RunThreadPool()
{
WorkerList.fill(std::make_shared<Worker>());
for (auto i = 0; i < ThreadNum; i++)
{
EventLoopList.at(i) = WorkerList.at(i)->ReturnEventLoopPtr();
}
}
std::shared_ptr<EventLoop> ThreadPool::GetNextEventLoop()
{
if (!EventLoopList.empty())
{
std::shared_ptr<EventLoop> nextLoop = EventLoopList[NextLoopIndex];
NextLoopIndex = (NextLoopIndex + 1) % ThreadNum;
return nextLoop;
}
return;
}
The error message is:
invalid use of data member ThreadPool::ThreadNum
In my opinion, the template parameter ThreadNum should be a constant, but now I need to infer its value when the class is constructed. Any solutions? Thank you very much.
What I am trying to do is add cards to a vector that is to be a Blackjack hand, but each time I enter the function that uses push_back to add a card to the vector, the vector starts out empty. The problem is in my Hand class in the addCardToHand function, and the same issue is present in the same class in my showHand function. I have whittled the code down as much as I could but still present a full working version with the issue. I cannot figure out why my Hand class treats the hand as brand new every time I call a function in the class. Please advise.
// Card.h
#ifndef CARD_H
#define CARD_H
#include <string>
#include <array>
class Card {
private:
int rank;
int suit;
int hardValue;
int softValue;
static const std::array<std::string,14> ranks;
static const std::array<std::string,5> suits;
public:
Card();
Card(int rank, int suit);
int getHardValue() const;
int getSoftValue() const;
std::string toString() const;
};
#endif
// Card.cpp
#include "Card.h"
const std::array<std::string,14> Card::ranks {"","A","2","3","4","5","6","7","8","9","10","J","Q","K"};
const std::array<std::string,5> Card::suits {"","C","D","H","S"};
Card::Card() : rank(0), suit(0) {
hardValue = 0;
softValue = 0;
}
Card::Card(int rank, int suit) : rank(rank), suit(suit) {
if (rank == 1) {
hardValue = 1;
softValue = 11;
}
else if (rank <= 10) {
hardValue = rank;
softValue = rank;
}
else {
hardValue = 10;
softValue = 10;
}
}
int Card::getHardValue() const {
return hardValue;
}
int Card::getSoftValue() const {
return softValue;
}
std::string Card::toString() const {
return ranks[rank] + suits[suit];
}
// Shoe.h
#ifndef SHOE_H
#define SHOE_H
#include <vector>
#include <random>
#include "Card.h"
class Shoe {
private:
int numDecksInShoe;
std::vector<Card> shoe;
static int currentCard;
static int maxDealCard;
static const unsigned long int seed;
static std::mt19937 randEng;
void renewShoe();
public:
Shoe();
explicit Shoe(int numDecksInShoe);
std::vector<Card> getShoe() const;
int getCurrentCard() const;
int getMaxDealCard() const;
void shuffle();
Card dealCard();
};
#endif
// Shoe.cpp
#include <ctime>
#include "Shoe.h"
const unsigned long int Shoe::seed = static_cast<unsigned long int>(std::time(nullptr));
std::mt19937 Shoe::randEng(seed);
int Shoe::currentCard = 0;
int Shoe::maxDealCard = 51;
Shoe::Shoe() {
}
Shoe::Shoe(int decksInShoe) {
numDecksInShoe = decksInShoe;
int count = 0;
for (int i = 0; i < numDecksInShoe; i++) {
for (int suit = 4; suit >= 1; suit--) {
for (int rank = 1; rank <= 13; rank++) {
Card card(rank,suit);
shoe.push_back(card);
count += 1;
}
}
}
currentCard = 0;
maxDealCard = count - 1;
}
std::vector<Card> Shoe::getShoe() const {
return shoe;
}
int Shoe::getCurrentCard() const {
return currentCard;
}
int Shoe::getMaxDealCard() const {
return maxDealCard;
}
void Shoe::shuffle() {
Card temp;
std::uniform_int_distribution<int> deckDist(0,numDecksInShoe*52-1);
int index;
for (int i = 0; i < numDecksInShoe*52; i++) {
do {
index = deckDist(randEng);
} while (index == i);
temp = shoe[index];
shoe[index] = shoe[i];
shoe[i] = temp;
}
std::uniform_int_distribution<int> maxDeal(10,41);
int tempMax = (numDecksInShoe-1)*52 - 1;
maxDealCard = tempMax + 51 - maxDeal(randEng);
}
Card Shoe::dealCard() {
if (currentCard == maxDealCard) {
renewShoe();
}
Card dealCard = shoe[currentCard];
currentCard += 1;
return dealCard;
}
void Shoe::renewShoe() {
Shoe newShoe(numDecksInShoe);
shoe = newShoe.getShoe();
shuffle();
}
here is my Hand class
// Hand.h
#ifndef HAND_H
#define HAND_H
#include <vector>
#include <string>
#include "Card.h"
class Hand {
private:
std::vector<Card> hand;
public:
Hand();
std::vector<Card> getHand() const;
void addCardToHand(Card card);
void clearHand();
Card revealBottomCard();
std::string showHand() const;
std::string peakHand() const;
};
#endif
// Hand.cpp
#include <iostream>
#include "Hand.h"
Hand::Hand() {
}
std::vector<Card> Hand::getHand() const {
return hand;
}
void Hand::addCardToHand(Card card) {
std::cout << card.toString() << std::endl;
hand.push_back(card);
}
void Hand::clearHand() {
hand.clear();
}
std::string Hand::showHand() const {
std::string returnString = "";
for (int i = hand.size()-1; i >= 1; i--) {
returnString += hand[i].toString() + "\n";
}
returnString += "XX\n";
return returnString;
}
std::string Hand::peakHand() const {
std::string returnString = "";
for (int i = hand.size()-1; i >= 0; i--) {
returnString += hand[i].toString() + "\n";
}
return returnString;
}
here is the Table class that has the code that calls the Hand class functions
// Table.h
#ifndef TABLE_H
#define TABLE_H
#include "Shoe.h"
#include "Player.h"
class Table {
private:
Shoe shoe;
public:
explicit Table(Shoe shoe);
Shoe getShoe() const;
void clearHand(std::vector<Player> players);
void dealHand(std::vector<Player> players);
};
#endif
// Table.cpp
#include <iostream>
#include "Table.h"
Table::Table(Shoe shoe) : shoe(shoe) {
}
Shoe Table::getShoe() const {
return shoe;
}
void Table::clearHand(std::vector<Player> players) {
for (Player &player : players) {
player.getHand().clearHand();
}
}
void Table::dealHand(std::vector<Player> players) {
for (int i = 0; i <= 1; i++) {
for (Player &player : players) {
player.getHand().addCardToHand(shoe.dealCard());
}
}
}
// Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include "Hand.h"
class Player {
private:
std::string name;
Hand hand;
double money;
public:
explicit Player(std::string name, double money = 1000.0);
std::string getName() const;
Hand getHand() const;
double getMoney() const;
};
#endif
// Player.cpp
#include "Player.h"
Player::Player(std::string name, double money) : name(name), money(money) {
}
std::string Player::getName() const {
return name;
}
Hand Player::getHand() const {
return hand;
}
double Player::getMoney() const {
return money;
}
and finally here is a short driver that runs and displays the issue
// blackjack testing
#include <iostream>
#include "Player.h"
#include "Table.h"
int main() {
std::vector<Player> players {Player("Tom",1500.0),Player("Sue"),Player("Dave")};
Shoe shoe1(6);
Table table1(shoe1);
table1.dealHand(players);
for (Player player : players) {
std::cout << player.getName() << "'s hand\n";
std::cout << player.getHand().showHand() << "\n\n";
}
}
The output is below. I printed out the cards that were added to the hand vector (and then 'forgotten') and below that above the XX's, if everything were to work correctly you should see the 4, 5 and 6 of spades since I did not shuffle the deck. The XX's are to simulate face down bottom card.
AS
2S
3S
4S
5S
6S
Tom's hand
XX
Sue's hand
XX
Dave's hand
XX
Sorry for dumping all this code in here, but I wanted to provide a full working solution and this is as small as I could get it. Thanks for any help.
player.getHand().addCardToHand(...);
player.getHand() returns a temporary Hand object that's a copy of player.hand. Then you add a card to that temporary object. Then that temporary object dies, added card and all. player.hand remains unchanged. This line of code is an elaborate no-op.
To add on #Igor's answer, the best way to fix this should probably return a reference instead:
const Hand& Player::getHand() const {
return hand;
}
I made this a const because returning a non-const could (potentially) allow you to break constness of a constant Player object. That is just inviting potential bugs.
Because of this, you may want to add a non-const version too:
Hand& Player::getHand() {
return hand;
}
Now you can't modify a const Player object, yet modify it properly when you need to.
I'm trying to use the DependencyCollector class of Clang in my Tool to list all the dependencies in a file, lets say test.cpp
Here is my program:
#include "stdafx.h"
#include <iostream>
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/Utils.h"
using namespace std;
using namespace clang::tooling;
using namespace clang;
using namespace llvm;
static cl::OptionCategory MyToolCategory("my-tool options");
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static cl::extrahelp MoreHelp("\nMore help text...");
class myDependencyCollector : public DependencyCollector {
private:
public:
bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem, bool IsModuleFile, bool IsMissing) {
if (Filename == "stdafx.h" || IsSystem) {
return false;
} else {
return true;
}
}
bool needSystemDependencies() {
return false;
}
};
class DependencyAction : public PreprocessOnlyAction {
private:
myDependencyCollector *col;
public:
virtual bool usesPreprocessOnly() const {
return true;
}
bool BeginSourceFileAction(CompilerInstance &ci) {
Preprocessor &pp = ci.getPreprocessor();
col = new myDependencyCollector();
col->attachToPreprocessor(pp);
return true;
}
void ExecuteAction() {
}
virtual void EndSourceFileAction() {
llvm::ArrayRef<string> arr = col->getDependencies();
int size = arr.size();
for (int i = 0; i < size; i = i+1) {
cout << arr[i] << endl;
}
}
};
int main(int argc, const char **argv)
{
CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList());
int result = Tool.run(newFrontendActionFactory<DependencyAction>().get());
return result;
}
Now, if I run the program on, for example the file test.cpp:
#include <iostream>
#include "test.h"
void do_math(int *x) {
*x += 5;
}
int main(void) {
int result = -1, val = 4;
do_math(&val);
return result;
}
The program doesn't find any includes.
It would be great if anybody could help me because I have not been able to find an answer after hours of searching on the internet.
The problem is that you overwrite the ExecuteAction() method from class PreprocessOnlyAction with an empty body.
If you delete the line:
void ExecuteAction() {}
everything works as expected.
I'm using netbeans with gcc compiler and when I try to declare an object of my class, and run the code I get the class was not delclared in this scope error, this is my code in main.cpp:
#include <cstdlib>
#include <iostream>
#include <cstring>
using namespace std;
int main() {
Clock r;
r.processH();
return 0;
}
class Clock {
private:
int h, m, s;
char conv[];
Clock() {
h = 0;
m = 0;
s = 0;
conv[10] = {};
}
public:
void processH() {
int r =0;
while(r <= 2){
conv[r] = 'I';
if(conv == "III") {
conv[0] = 'V';
conv[1] = 'I';
r++;
break;
}
r++;
}
cout<< r;
}
};
What am I doing wrong? I'm not an experienced OOP programmer.
First, you should declare the class before you use it's name. In your case it should be above the main function.
Second, you declared Reloj function with no return type, which is illegal.
The correct code may look like this:
#include <cstdlib>
#include <iostream>
#include <cstring>
using namespace std;
class Clock {
private:
int h, m, s;
char conv[];
void Reloj() {
h = 0;
m = 0;
s = 0;
conv[10] = {};
}
public:
void processH(int ent) {
int r =0;
while(r <= 2) {
conv[r] = 'I';
if(conv == "III") {
conv[0] = 'V';
conv[1] = 'I';
r++;
break;
}
r++;
}
cout<< r;
}
};
int main() {
Clock r;
r.processH(5);
return 0;
}
Just a complement to Sergey's answer : You could also forward declare the class.
Just add the line
class Clock;
before your main function to tell the compiler that the class exists.
I'm trying to pass an instance of this (the instance in question being the GameEngine class) into my PlayerBrain.run method which takes a GameEngine * const argument corresponding to what this is. I'm curious as to what would cause such an error to be thrown in this case, especially when there are no alternative function definitions for run() or anything like that. PlayerBrain is its own class, not descending from anything. So there's no alternative definitions to run that might cause problems. Here's the relevant code:
All public methods in PlayerBrain.h
#pragma once
#include "GameEngine.h"
#include "Species.h"
#include "Neuron.h"
#include "Genome.h"
#include "GenePool.h"
#include "Gene.h"
#include <sys/stat.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
class PlayerBrain {
private:
int popSize;
int stalenessThreshold;
int timeoutConstant;
int currentTimeout;
int maxNodes;
int farthestDistance;
bool buttons[6]; // JASON - shoot, left, right, up, down, jump in that order
GenePool p;
bool fileExists(string filename);
bool fitnessAlreadyMeasured();
void nextGenome();
void evaluateCurrent(Genome * g);
void evaluateNetwork(vector<Neuron*> * network, vector<int> inputs);
void loadPool(string filename);
double sigmoid(double sum);
vector<int> getInputs();
Genome templateGenome();
void pressAKey();
void unPressAKey();
vector<INPUT *> oldbuttons;
public:
PlayerBrain();
void intialize();
void run(GameEngine const *);
void close();
};
The actual implementation in its .cpp
void PlayerBrain::run(GameEngine const * g) {
Genome * current = p.getCurrentGenome();
int xPos = 0;
int bossLives = 0;
double fitness;
double timeoutBonus;
unPressAKey();
if ((p.getCurrentFrame() % 5) == 0)
evaluateCurrent(current);
pressAKey();
xPos = g->getXPosAckVar();
bossLives = g->getBossLivesAckVar();
if (xPos > farthestDistance) { farthestDistance = xPos; currentTimeout = timeoutConstant; }
currentTimeout--;
timeoutBonus = p.getCurrentFrame() / 4;
if ((currentTimeout + timeoutBonus) <= 0) {
fitness = (farthestDistance - (p.getCurrentFrame() / 2)) + 2000 * bossLives;
if (fitness == 0) { fitness = -1; }
current->setFitness(fitness);
if (fitness > p.getMaxFitness()) { p.setMaxFitness(fitness); }
p.setCurrentSpecies(0);
p.setCurrentGenome(0);
while (fitnessAlreadyMeasured()) { nextGenome(); }
}
p.setCurrentFrame(p.getCurrentFrame() + 1);
}
The function call in GameEngine.cpp`
while (true)
{
......//irrelevant stuff
if (tickTimeNow > tickTimeTrigger)
{
if (dTimeTrigger > m_PaintTimeTrigger)
{
....
brain->run(this);
....
}
else Sleep(1);
}
else WaitMessage();
}
}
The error I get is as follows:
Error C2660 'PlayerBrain::run': function does not take 1 arguments