pointer array C++ - c++

I wanna make a pointer array that holds address of objects in that class so when i call scanner function it ll read pcode and search for objects has the same pcode. am i declaring array wrong? or did i misunderstand static concept? or something else ?
anyways i guess have to posting whole code
#include <string>
using namespace std;
class product{
public:
product();
product(long&,string&);
void setCode();
void getCode(long);
void static scanner();
void const printer();
static product *point[3];
static int a;
private:
string pname;
long pcode;
};/*
class PrepackedFood:public product{
public:
PrepackedFood(long&, string&,double);
private:
double uPrice;
};
class FreshFood:public product{
public:
FreshFood(long&,string&,double,double);
private:
double weight;
double pricepk;
};*/
#include "product.h"
#include <iostream>
product::product(){pcode=0;pname="unknown";
point[a]= this;
a++;}
product::product(long& c,string&n){pcode=c;pname=n;
}
//void const product::printer(){cout<<getCode()}
void product::setCode(){ cout<<"enter product name\n ";cin>>pname;
cout<<"enter product code _____\b\b\b\b\b";cout<<"\a";
cin>>pcode;cout<<endl;
cout<<pname<<endl;
cout<<pcode<<endl;
}
void product::getCode(long s){
if ((*this).pcode=s){
printer();
}
}
void product::scanner(){
long a;
cout<<"SCANNING!\a_____\b\b\b\b\b";cin>>a;
int i=0;
while(i<3){
if (point[i]->pcode==a){point[i]->printer();
break;
}
i++;
//(i==3)?cout<<"try again\n":"\a";
}
}
void const product::printer(){
cout<<pname<<endl;
cout<<pcode<<endl;
}
#include "product.h"
int main(){
product a[3];
int i=0;
while(i<3){
a[i].setCode();
i++;
}
product::scanner();
return 0;
}
i know it can be done a lot more easily i am just learning so just wanna fix scanner function. it doesn't compile
1>product.obj : error LNK2001: unresolved external symbol "public: static class product * * product::point" (?point#product##2PAPAV1#A)
1>product.obj : error LNK2001: unresolved external symbol "public: static int product::a" (?a#product##2HA)

The code looks like a mess.
The solution to your linker problem is in defining the already declared static point member:
product* product::point[3];

Is it not compiling, or is it compiling and crashing? Always say exactly what the problem is when posting. I can see some runtime problems in it easily though.
In your loop, you're always touching the pointers at point[0], point[1], and point[2]. However, you never initialize these to null or do null checks. So if you haven't called the constructor 3 times before calling scanner, you will segfault as one or more of these pointers will be invalid.
Also, your constructor never checks for overflow, so if you call the constructor more than 3 times it will segfault. And if you're ever passing objects back and forth directly from functions remember that the compiler may insert temporary object constructors.

Related

Trying to use static class variable to create new ID for objects

I am new to C++ and when I try to run this program it tells me: "error LNK2001: unresolved external symbol "private: static int Plate::plate_nID". I am right now just trying to create the plate class and print out the ID. Not sure where I went wrong.
#pragma once
#include <string>
using namespace std;
class Plate{
private:
int id;
string plateName;
static int plate_nID;
int generateID(){
plate_nID++;
return plate_nID;
}
public:
Plate(string name){
plateName = name;
id = generateID();
}
~Plate(){}
int getID(){
return id;
}
string getName(){
return plateName;
}
};
Here is my main:
#include "Plate.cpp"
#include "PlateNode.cpp"
using namespace std;
int main(){
Plate s=Plate::Plate("p1");
cout << s.getID();}
I have looked at this question:
Undefined reference to static class member
which similar questions to mine were marked as dulpicates of, but I when I try to do that it tells me: cannot instantiate non-static member outside of class. Please Help!
You need to define the static variable outside your class, only then will your code work
int Plate::plate_nID = 0;
You must define it outside the class (preferably outside the main() )
Probably better to define it right after your class.
You need to define the static member variable outside the class. Something along the lines of:
int Plate::plate_nID = 0;

How can I create a vector of virtual class?

I'm new to C++, so I decided to work on some little project to improve myself. I try to write a simple chess program with class Unit, and class King which is inherited from Unit
#include <list>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stdlib.h> /* abs */
using namespace std;
// Each unit class represent a chess unit
class Unit{
protected:
int currentX;
int currentY;
string side;
public:
Unit();
Unit(string sideplay, int Xpos,int Ypos)
{
currentX=Xpos; currentY= Ypos;side=sideplay;
}
int getX()
{
return currentX;
}
int getY()
{
return currentY;
}
string getside()
{
return side;
}
void setpos(int newX,int newY) //set new position
{
currentX=newX;
currentY=newY;
}
bool validmove(vector<Unit> unitlist ,string sidepick,int Xpos,int Ypos)
{ int i=0;
while(i != 3)
{ int X=unitlist[i].getX();
int Y=unitlist[i].getY();
string sidetemp= unitlist[i].getside();
if ((X==Xpos)&&(Y==Ypos)&&(sidetemp==sidepick))
{
return false;
}
else if ((X==Xpos)&&(Y==Ypos)&&(sidetemp!=sidepick))
{ //unitlist[i]=NULL;
return true;
}
i++;
}
return true;
}
virtual void moveunit(vector<Unit> unitlist ,int nextX,int nextY);
};
class King: public Unit{
public:
King(string sideplay, int Xpos,int Ypos):Unit(sideplay,Xpos,Ypos)
{}
void moveunit(vector<Unit> unitlist ,int nextX,int nextY){
int diffX=abs(nextX-currentX);
int diffY=abs(nextY-currentY);
if ((diffX==1)||(diffY==1))
{ if (validmove(unitlist,side,nextX,nextY))
{
setpos(nextX,nextY);}
}
}
};
and here is my main:
int main()
{
vector<Unit> chessunit;
chessunit.push_back(King("white",3,1));
chessunit.push_back(King("black",3,2));
chessunit.push_back(King("white",4,1));
if (chessunit[0].validmove(chessunit,"white",3,2))
{
cout<<"hehe"<<endl;
}
chessunit[0].moveunit(chessunit,3,2);
int k= chessunit[0].getY();
cout<<k<<endl;
return 0;
}
I keep getting LNK 2001 error: Unresolved external symbol for my virtual method "moveunit". How can I fix that bug ?
The easiest way of fixing your problem is using pointers or smart pointers: Store vector<Unit*>, vector<std::shared_ptr<Unit>> or vector<std::unique_ptr<Unit>> (thanks #rubenvb) instead of vector<Unit> and then add your kings like so:
myVector.push_back(new King...); // or
myVector.push_back(std::shared_ptr<King>(new King...)); // or
myVector.push_back(std::unique_ptr<King>(new King...));
Why?
If you allocate an object of a virtual class (e.g. Unit unit) and you want to assign an object of an implementation of that class to it, e.g.:
Unit unit;
unit = King(...);
Then you will get an error, or at least run into trouble, unless you provide a constructor for Unit that takes King as an argument or provide a sufficient move operator. That is because if you try to assign an object of a type that is not Unit to unit, the compiler and/or run-time (depending on what the back-end of your compiler is) will have a tough time figuring out how compatible the types are and what to do if things "don't fit" memory-wise and how to cope with memory layout issues.
Further Reading
For more on pointers vs. smart pointers, consider this thread. Also here is a related Stackoverflow question and an article on using shared_ptr with STL collections
More information on trying to "squeeze" an object of one type into another (called slicing) can be found in this thread.
The problem you are facing right now is due to slicing: when you add a King to the vector, it gets sliced into an instance of Unit.
One way to fix this is to turn chessunit into a vector of std::shared_ptr<Unit> and allocate units on the heap.
P.S. Since you are not defining Unit::moveunit(), make it pure virtual:
virtual void moveunit(vector<Unit> unitlist ,int nextX,int nextY) = 0;
^^^

Unidentified reference to constructor (c++) [duplicate]

This question already has answers here:
Undefined reference C++
(2 answers)
Closed 9 years ago.
I have done some research and googling on this error for days, as far as I know this is a common problem for many in c++, I still haven't found a clear answer to this error. I've read that linking the files can fix this, but I could find any example codes to do this. I'am so close to finishing this code, all I need to do to call the constructor from the main file (or just make a simple object), but I keep getting this "unidentified reference to NamedStorm::NamedStorm()" error, please help.
MAIN.CPP
#include <iostream>
#include <string>
#include "NamedStorm.h"
using namespace std;
NamedStorm storm[2];
int main(){
// NamedStorm Chris("Chris", 70.0, "T.S.", 990.0);
// storm[0] = Chris;
return 0;
}
NamedStorm.cpp
// CPP => Function definition
#include <string>
#include "NamedStorm.h"
using namespace std;
// Defining static variables
int NamedStorm::stormCount = 0;
// Constructor definition
NamedStorm::NamedStorm(std::string sName, double wSpeed, std::string sCat, double sPress){
stormName = sName;
windSpeed = wSpeed;
stormCategory = sCat;
stormPressure = sPress;
stormCount++;
}
NamedStorm::NamedStorm(std::string sName){
stormName = sName;
stormCount++;
}
NamedStorm::NamedStorm(){
stormName = sName;
stormCount++;
}
// Destructor definition
//NamedStorm::~NamedStorm(){}
// Get (Accessor) function definition
int NamedStorm::getStormCount(){
return stormCount;
}
double NamedStorm::getStormPressure(){
return stormPressure;
}
string NamedStorm::getStormCategory(){
return stormCategory;
}
string NamedStorm::getName(){
return stormName;
}
// Set (Mutator) function definition
void NamedStorm::displayOutput(){}
void NamedStorm::sortByNames(){}
void NamedStorm::getAverageStormPressure(){}
void NamedStorm::getAverageWindSpeed(){}
void NamedStorm::getWindSpeed(){}
NamedStorm.h
#ifndef NAMEDSTORM_H_INCLUDED
#define NAMEDSTORM_H_INCLUDED
// NEVER use using namespce in header, use std instead.
class NamedStorm{
private:
std::string stormName;
std::string stormCategory;
double maxWindSpeed;
double stormPressure;
static int stormCount;
public:
// Constructor
NamedStorm(std::string, double, std::string, double);
NamedStorm(std::string);
NamedStorm();
// Destructor
//~NamedStorm();
// Get functions
int getStormCount();
double getStormPressure();
double getWindSpeed();
std::string getStormCategory();
std::string getName();
// Set functions
static void displayOutput();
static void sortByNames();
static void sortByWindSpeed();
static void getAverageWindSpeed();
static void getAverageStormPressure();
};
#endif // NAMEDSTORM_H_INCLUDED
Why is the definition of the default constructor the same as of the NamedStorm::NamedStorm(std::string) ? I would start from correcting that.

Calling a method from a constructor in another class c++

I need to call a method from one class in the constructor of another class. I am not sure how to do this without getting a "was not declared in this scope" error. Note I am just learning C++.
See the comments in symboltable.cpp for what I am trying to accomplish here. I am not looking for anyone to do it for me. I could use an example or pointed in the right direction so I can figure this out.
symboltable.h code:
class SymbolTable
{
public:
SymbolTable() {}
void insert(string variable, double value);
void insert(string variable); // added for additional insert method
double lookUp(string variable) const;
void init(); // Added as mentioned in the conference area.
private:
struct Symbol
{
Symbol(string variable, double value)
{
this->variable = variable;
this->value = value;
}
string variable;
double value;
};
vector<Symbol> elements;
};
symboltable.cpp code:
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
#include "symboltable.h"
/* Implementing the "unreferenced variable" warning.
* Modify the symbol table by adding another insert method
* that supplies only the variable name.
* This method should be called when the variable name
* is encountered while building the arithmetic expression tree.
* It would be called in the constructor of the Variable class.
* The existing insert method, which is called when an assignment is encountered,
* would first check to see whether it is already in the symbol table.
* If it is not, then it is unreferenced.
*/
void SymbolTable::insert(string variable, double value)
{
/* This existing insert method, which is called when an assignment is encountered,
* first needs to check to see whether it is already in the symbol table.
* If it is not, then it is unreferenced.
* */
//Need to check if variable is in the expression need to find out how the expression is stored!
if (find(elements.begin(), elements.end(), variable)) {
const Symbol& symbol = Symbol(variable, value);
elements.push_back(symbol);
} else
throw string("Error: Test for output");
}
/* Adding another insert method that supplies only the variable name.
* This method should be called when the variable name is encountered
* while building the arithmetic expression tree.
* It should be called in the constructor of the Variable class.
*/
void SymbolTable::insert(string variable)
{
const Symbol& symbol = Symbol(variable, symbolTable.lookUp(variable));
elements.push_back(symbol);
}
double SymbolTable::lookUp(string variable) const
{
for (int i = 0; i < elements.size(); i++)
if (elements[i].variable == variable)
return elements[i].value;
else
throw "Error: Uninitialized Variable " + variable;
return -1;
}
void SymbolTable::init() {
elements.clear(); // Clears the map, removes all elements.
}
variable.h code:
class Variable: public Operand
{
public:
Variable(string name) //constructor
{
// how do i call symbolTable.insert(name); here
// without getting 'symboleTable' was not declared in this scope error
this->name = name;
}
double evaluate();
private:
string name;
};
variable.cpp code:
#include <string>
#include <strstream>
#include <vector>
using namespace std;
#include "expression.h"
#include "operand.h"
#include "variable.h"
#include "symboltable.h"
extern SymbolTable symbolTable;
double Variable::evaluate() {
return symbolTable.lookUp(name);
}
There are two solutions:
You use a global variable - like your Variable::evaluate() example. You can of course add your Variable::Variable() as a function in "variable.cpp" instead of the header. Or you can just put a extern SymbolTable symbolTable to the file "variable.h".
You pass in a reference to symbolTable into the constructor (and perhaps store that inside the Variable object - that way, symbolTable doesn't need to be a global variable at all.
By the way, it's generally considered bad style to add using namespace std before header files.
extern SymbolTable symbolTable; needs to go into the header file that is included by everyone who needs symbolTable. Then, in variable.cpp, you need to have SymbolTable symbolTable;
You need to instantiate the second class, either within the constructor, which will make it and its members available only within the constructor of the first class, or in the global namespace. For example:
MyFooClass CFoo;
MyBarClass CBar;
MyFooClass::MyFooClass()
{
CBar = new MyBarClass();
CBar.BarClassMemberFunction();
}

Why can't my compiler find my function?

I am just learning how to use C/C++ and am trying to write a program in which "otherPerson" (first name, last name) inherits from "person" (first name). I'm stuck on the compareTo function for person. It is supposed to sort an array of pointers to person alphabetically by first name. (not sure if I expressed that idea correctly). The end goal is to print the sorted contents of the array.
I keep getting:
error LNK2019: unresolved external symbol "void __cdecl compareTo(class person * * const,int)" (?compareTo##YAXQAPAVperson##H#Z) referenced in function _main
1>c:\users\laur\documents\visual studio 2012\Projects\Project1\Debug\Project1.exe : fatal error LNK1120: 1 unresolved externals
when I try to build. I've looked around the internet for more information, but I'm pretty sure my include statements are correct. The function is intended as a member function.
Test.cpp:
#include "stdio.h"
#include "otherPerson.h"
#include<iostream>
#include <string>
using namespace std;
void compareTo(person *array[7], int );
int main(){
int length = 7;
person* epicJourney[6];
//fill array
compareTo(epicJourney, length);
person.h:
#include <stdio.h>
#include <string>
using namespace std;
class person {
protected:
string firstName;
public:
person(string firstName);
virtual void setFirstName(string firstName);
virtual string getFirstName();
virtual void compareTo (person *array[7], int length);
virtual string toString();
};
person.cpp:
#include "person.h"
#include <string>
using namespace std;
person::person(string firstName){
this->firstName = firstName;
}
void person::setFirstName(string aName){
firstName =aName;
}
string person::getFirstName(){
return ((*this).firstName);
}
string person::toString(){
return (this->firstName);
}
void person::compareTo(person *array[], int length){
int i;
int j;
person *current;
for (i=1; i<length; i++){
current = array[i];
for (j=i; j>=1 && (current < array[j-1]); j--){
array[j] = array[j-1];
array[j-1] = current;
}
}
}
You prototype is void compareTo(... ); but your actual implementation is void person::compareTo(...) . You have to make up your mind: do you want a class member function?
You're missing the definition of this standalone function, :
void compareTo(person *array[7], int );
You need to add the definition in your program somewhere.
You define a function person::compareTo, which is different from the function compareTo declared in Test.cpp (because the former is a member function of person, while the latter is a global function).