C++ Undeclared Identifier on Object creation - c++

So I am new to c++, coming from C#. This is giving me several errors when compiling, which all seem to relate to this object declaration. Anyone able to show me the right way to do this?
I get an undeclared identifier where i declare tri(sideLength).
I have used this as a reference for object declaration, but it doesn't seem to be helping me.
Thanks.
#include <iostream> // Provides cout
#include <iomanip> // Provides setw function for setting output width
#include <cstdlib> // Provides EXIT_SUCCESS
#include <cassert> // Provides assert function
#include <stdexcept>
#include <math.h>
using namespace std; // Allows all standard library items to be used
void setup_cout_fractions(int fraction_digits)
// Precondition: fraction_digits is not negative.
// Postcondition: All double or float numbers printed to cout will now be
// rounded to the specified digits on the right of the decimal.
{
assert(fraction_digits > 0);
cout.precision(fraction_digits);
cout.setf(ios::fixed, ios::floatfield);
if (fraction_digits == 0)
cout.unsetf(ios::showpoint);
else
cout.setf(ios::showpoint);
}
int main()
{
const int MAX_SIDE_LENGTH = 6;
const int INITIAL_LENGTH = 1;
const int DIGITS = 4;
const int ARRAY_SIZE = 6;
// Set up the output for fractions and print the table headings.
setup_cout_fractions(DIGITS);
// Each iteration of the loop prints one line of the table.
for (int sideLength = 0; sideLength < MAX_SIDE_LENGTH; sideLength += 1)
{
EquilateralTriangle tri(sideLength);
//Square sq(sideLength);
//Pentagon_Reg pent(sideLength);
//Hexagon_Reg hex(sideLength);
//Heptagon_Reg hept(sideLength);
//Octagon_Reg octa(sideLength);
cout << "Type: " << tri.Name() << "has area: " << tri.Area() << " with SideLength = " << sideLength;
}
return EXIT_SUCCESS;
}
//Template
class GeometricFigure
{
public:
GeometricFigure() { }
double SideLength;
virtual double Area() { return 0; };
virtual char* Name() { return ""; };
};
class EquilateralTriangle : public GeometricFigure {
public:
EquilateralTriangle(double sideLength)
{
SideLength = sideLength;
}
char* Name() { return "Equilateral Triangle"; }
double Area() { return (sqrt(3) / 2 * pow(SideLength, 2)); }
};

In C++, the compiler reads your code from top-to-bottom, once. This is a holdover from when early C compilers only had a few kilobytes of memory to work with - C was designed so that a compiler would only need to look at a little bit of the code at a time.
Because of this, things must have been declared or defined as necessary, before you try to use them.
Move both classes somewhere before main. GeometricFigure must be before EquilateralTriangle, and EquilateralTriangle must be before main.

You would need to "declare" or tell the compiler, where to look for the EquilateralTriangle and GeometricFigure, "before" you use it first. you might want to take a look at the similar discussion at - C# declarations vs definitions

Related

How to output a variable stored in another variable

So here's my code at the moment:
#include <iostream>
using namespace std;
int main() {
string x = "_one";
int sound_one = 7;
int sound_two = 8;
cout << ("sound") + x;
}
However when I run the code, it outputs 'sound_one' instead of '7'. How do I get it to output the variable sound_one instead of just 'sound_one'? Also, I need it so I can change x to different things (eg '_two') so it will then output sound_two instead. Any help would be greatly appreciated.
C++ is not a reflective language in the sense that you can acquire a variable name at runtime (variable names are normally compiled out of the program). You can use std::map though to achieve your immediate aim:
#include <iostream>
#include <string>
#include <map>
int main() {
using std::literals::string_literals::operator""s;
std::string x = "_one";
std::map<std::string, int> data;
data["sound_one"] = 7;
data["sound_two"] = 8;
std::cout << data["sound"s + x];
}
Note the notation "sound"s: the suffixed s denotes a std::string user defined literal.
You can't a variable from a string in this way. A work around is to use if/switch statements until the variable name is matched and then print it:
if(x == "_one") {
cout << sound_one;
}
else if(x == "_two") {
cout << sound_two;
}
else {
cout << "no match";
}
You can't do that in C++. You can use a map as shown in another answer, but I feel like what you really need is an array:
#include <format>
#include <iostream>
int main()
{
int data[] { 7, 8 };
std::cout << std::format("data[{}] = {}\n", 0, data[0]);
}
Arrays are usually better for such simple ordered sequences.

Should I be attempting to return an array, or is there a better solution?

A problem set for people learning C++ is
Write a short program to simulate a ball being dropped off of a tower. To start, the user should be asked for the initial height of the tower in meters. Assume normal gravity (9.8 m/s2), and that the ball has no initial velocity. Have the program output the height of the ball above the ground after 0, 1, 2, 3, 4, and 5 seconds. The ball should not go underneath the ground (height 0).
Before starting C++ I had a reasonable, but primarily self taught, knowledge of Java. So looking at the problem it seems like it ought to be split into
input class
output class
calculations class
Physical constants class (recommended by the question setter)
controller ('main') class
The input class would ask the user for a starting height, which would be passed to the controller. The controller would give this and a number of seconds (5) to the calculations class, which would create an array of results and return this to the controller. The controller would hand the array of results to the output class that would print them to the console.
I will put the actual code at the bottom, but it's possibly not needed.
You can probably already see the problem, attempting to return an array. I'm not asking how to get round that problem, there is a workaround here and here. I'm asking, is the problem a result of bad design? Should my program be structured differently, for performance, maintenance or style reasons, such that I would not be attempting to return an array like object?
Here is the code (which works apart from trying to return arrays);
main.cpp
/*
* Just the main class, call other classes and passes variables around
*/
#include <iostream>
#include "dropSim.h"
using namespace std;
int main()
{
double height = getHeight();
int seconds = 5;
double* results = calculateResults(height, seconds);
outputResults(results);
return 0;
}
getHeight.cpp
/*
* Asks the user for a height from which to start the experiment
* SI units
*/
#include <iostream>
using namespace std;
double getHeight()
{
cout << "What height should the experiment start at; ";
double height;
cin >> height;
return height;
}
calculateResults.cpp
/*
* given the initial height and the physical constants, the position of the ball
* is calculated at integer number seconds, beginning at 0
*/
#include "constants.h"
#include <cmath>
#include <iostream>
using namespace std;
double getPosition(double height, double time);
double* calculateResults(double height, int seconds)
{
double positions[seconds + 1];
for(int t = 0; t < seconds + 1; t++)
{
positions[t] = getPosition(height, t);
}
return positions;
}
double getPosition(double height, double time)
{
double position = height - 0.5*constants::gravity*pow(static_cast<double>(time), 2);
if( position < 0) position = 0;
//Commented code is for testing
//cout << position << endl;
return position;
}
outputResults.cpp
/*
* Takes the array of results and prints them in an appropriate format
*/
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
void outputResults(double* results){
string outputText = "";
//The commented code is to test the output method
//Which is working
//double results1[] = {1,2,3,4,5};
//int numResults = sizeof(results1)/sizeof(results1[0]);
int numResults = sizeof(results)/sizeof(results[0]);
//cout << numResults; //= 0 ... Oh
for(int t = 0; t < numResults; t++)
{
ostringstream line;
line << "After " << t << " seconds the height of the object is " << results[t] << "\r";
outputText.append(line.str());
}
cout << outputText;
}
And finally a couple of headers;
dropSim.h
/*
* dropSim.h
*/
#ifndef DROPSIM_H_
#define DROPSIM_H_
double getHeight();
double* calculateResults(double height, int seconds);
void outputResults(double* results);
#endif /* DROPSIM_H_ */
constants.h
/*
* Contains physical constants relevant to simulation.
* SI units
*/
#ifndef CONSTANTS_H_
#define CONSTANTS_H_
namespace constants
{
const double gravity(9.81);
}
#endif /* CONSTANTS_H_ */
I would say that you're over-engineering a big solution to a little problem, but to answer your specific question:
Should my program be structured differently, for performance, maintenance or style reasons, such that I would not be attempting to return an array like object?
Returning an array-like object is fine. But that doesn't mean returning an array, nor does it mean allocating raw memory with new.
And it's not restricted to return values either. When you're starting out with C++, it's probably best to just forget that it has built-in arrays at all. Most of the time, you should be using either std::vector or std::array (or another linear collection such as std::deque).
Built-in arrays should normally be viewed as a special-purpose item, included primarily for compatibility with C, not for everyday use.
It may, however, be worth considering writing your computation in the same style as the algorithms in the standard library. This would mean writing the code to receive an iterator to a destination, and writing its output to wherever that iterator designates.
I'd probably package the height and time together as a set of input parameters, and have a function that generates output based on those:
struct params {
double height;
int seconds;
};
template <class OutIt>
void calc_pos(params const &p, OutIt output) {
for (int i=0; i<p.seconds; i++) {
*output = get_position(p.height, i);
++output;
}
}
This works somewhat more clearly along with the rest of the standard library:
std::vector<double> results;
calc_pos(inputs, std::back_inserter(results));
You can go a few steps further if you like--the standard library has quite a bit to help with a great deal of this. Your calc_pos does little more than invoke another function repeatedly with successive values for the time. You could (for example) use std::iota to generate the successive times, then use std::transform to generate outputs:
std::vector<int> times(6);
std::iota(times.begin(), times.end(), 0);
std::vector<double> distances;
std::transform(times.begin(), times.end(), compute_distance);
This computes the distances as the distance dropped after a given period of time rather than the height above the ground, but given an initial height, computing the difference between the two is quite trivial:
double initial_height = 5;
std::vector<double> heights;
std::transform(distances.begin(), distances.end(),
std::back_inserter(heights),
[=](double v) { return max(initial_height-v, 0); });
At least for now, this doesn't attempt to calculate the ball bouncing when it hits the ground--it just assumes the ball immediately stops when it hits the ground.
You should get rid of self-allocated double * and use std::vector<double> instead. It's not difficult to learn and a basic step in modern C++
This is how I would solve the problem:
#include <cmath>
#include <iostream>
#include <iomanip>
using std::cin;
using std::cout;
using std::endl;
using std::sqrt;
using std::fixed;
using std::setprecision;
using std::max;
using std::setw;
static const double g = 9.81;
class Calculator {
public:
Calculator(double inh) : h(inh)
{
}
void DoWork() const {
double tmax = sqrt(h / ( g / 2));
for (double t=0.0; t<tmax; t+=1.0) {
GenerateOutput(t);
}
GenerateOutput(tmax);
}
private:
void GenerateOutput(double t) const {
double x = g * t * t / 2;
double hremaining = max(h - x, 0.0);
cout << fixed << setprecision(2) << setw(10) << t;
cout << setw(10) << hremaining << endl;
}
double h;
};
int main() {
double h(0.0);
cout << "Enter height in meters: ";
cin >> h;
if (h > 0.0) {
const Calculator calc(h);
calc.DoWork();
} else {
return 1;
}
return 0;
}

Same variable for different datatypes?

I have to call one simple functions with different datatypes in c++. eg,
void Test(enum value)
{
int x;
float y; // etc
if(value == INT)
{
// do some operation on x
}
else if(value == float)
{
// do SAME operation on y
}
else if(value == short)
{
// AGAIN SAME operation on short variable
}
.
.
.
}
Thus I want to eliminate the repetitive code for different datatypes ...
So , I tried to use macro ,depending on values of enum, to define same variable for different datatypes .. but then not able to differentiate between the MACROS
e.g.
void Test(enum value)
{
#if INT
typedef int datatype;
#elif FLOAT
typedef float datatype;
.
.
.
#endif
datatype x;
// Do operation on same variable
}
But now every time the first condition #if INT is getting true.
I tried to set different values of macro to differentiate but not working :(
Can anyone help me achieve the above thing.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
//type generic method definition using templates
template <typename T>
void display(T arr[], int size) {
cout << "inside display " << endl;
for (int i= 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
int main() {
int a[10];
string s[10];
double d[10];
for (int i = 0; i < 10; i++) {
a[i] = i;
d[i] = i + 0.1;
stringstream std;
std << "string - "<< i;
s[i] = std.str();
}
display(a, 10); //calling for integer array
display(s, 10); // calling for string array
display(d, 10); // calling for double array
return 0;
}
If you really want your function to be generic, template is the way to go. Above is the way to do and call the method from main method. This might be of some help for you to reuse a function for different types. Pick up any tutorial or C++ books for complete understanding on templates and get a grip of the full concepts. Cheers.
You can use templates to achieve you purpose.
Simply write a template function which take the value in the function argument which is of generic type and put the operational logic inside it. Now call the function with different data types.
I advice you to use function overloading:
void foo(int arg) { /* ... */ }
void foo(long arg) { /* ... */ }
void foo(float arg) { /* ... */ }
Supposing you want do the same operation with integer and long types you can eliminate the code repetition in this way:
void foo(long arg) { /* ... */ }
void foo(int arg) { foo((long) arg); }

Error C3861: 'ResGain': identifier not found

essentially I'm writing a short script. The easiest way to look at is that it's for a game with a resource collection. ResGain is the resources gained, and BonusGain is the chance to earn an extra resource. I am getting Identifier not found errors for the ResGain and Bonus Gain functions, but I have declared the ResGain and BonusGain functions before main. Any ideas why?
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
float ResGain(float u, int r) //calc Base resource Gain
{
float lapout;
lapout = r * u;
return (lapout);
}
char BonusGain(int b) //Determines if a bonus material would be produced.
{
char bonus;
int rng;
rng = rand() % 100 + 1;
if (rng <= b)
bonus = 1;
return(bonus);
}
int main()
{
float l;
l = ResGain(1.1,70);
cout << "You have earned" << l << "Lapis";
if (BonusGain(3)==1)
cout << "You have also earned a bonus material";
system("pause");
return 0;
}
Most probably the identifier not found is system() which is not part of the standard library. You should locate the Windows-specific header where it is declared.

Getting segmentation fault after destructor

I'm making a small file reading and data validation program as part of my TAFE (a tertiary college) course, This includes checking and validating dates.
I decided that it would be best done with a seperate class, rather than integrating it into my main driver class.
The problem is that I'm getting a segmentation fault(core dumped) after my test program runs. Near as I can tell, the error occurs when the program terminates, popping up after the destructor is called. So far I have had no luck finding the cause of this fault, and was hoping that some enlightened soul might show me the error of my ways.
date.h
#ifndef DATE_H
#define DATE_H
#include <string>
using std::string;
#include <sstream>
using std::stringstream;
#include <cstdlib>
using std::exit;
#include <iostream>
using std::cout;
using std::endl;
class date {
public:
explicit date();
~date();
bool before(string dateIn1, string dateIn2);
int yearsBetween(string dateIn1, string dateIn2);
bool isValid(string dateIn);
bool getDate(int date[], string dateIn);
bool isLeapYear(int year);
private:
int days[];
};
#endif
date.cpp
#include "date.h"
date::date() {
days[0] = 31;
days[1] = 28;
days[2] = 31;
days[3] = 30;
days[4] = 31;
days[5] = 30;
days[6] = 31;
days[7] = 31;
days[8] = 30;
days[9] = 31;
days[10] = 30;
days[11] = 31;
}
bool date::before(string dateIn1, string dateIn2) {
int date1[3];
int date2[3];
getDate(date1, dateIn1);
getDate(date2, dateIn2);
if (date1[2] < date2[2]) {
return true;
} else if (date1[1] < date2[1]) {
return true;
} else if (date1[0] < date2[0]) {
return true;
}
return false;
}
date::~date() {
cout << "this is for testing only, plox delete\n";
}
int date::yearsBetween(string dateIn1, string dateIn2) {
int date1[3];
int date2[3];
getDate(date1, dateIn1);
getDate(date2, dateIn2);
int years = date2[2] - date1[2];
if (date1[1] > date2[1]) {
years--;
}
if ((date1[1] == date2[1]) && (date1[0] > date2[1])) {
years--;
}
return years;
}
bool date::isValid(string dateIn) {
int date[3];
if (getDate(date, dateIn)) {
if (date[1] <= 12) {
int extraDay = 0;
if (isLeapYear(date[2])) {
extraDay++;
}
if ((date[0] + extraDay) <= days[date[1] - 1]) {
return true;
}
}
} else {
return false;
}
}
bool date::getDate(int date[], string dateIn) {
string part1, part2, part3;
size_t whereIs, lastFound;
whereIs = dateIn.find("/");
part1 = dateIn.substr(0, whereIs);
lastFound = whereIs + 1;
whereIs = dateIn.find("/", lastFound);
part2 = dateIn.substr(lastFound, whereIs - lastFound);
lastFound = whereIs + 1;
part3 = dateIn.substr(lastFound, 4);
stringstream p1(part1);
stringstream p2(part2);
stringstream p3(part3);
if (p1 >> date[0]) {
if (p2>>date[1]) {
return (p3>>date[2]);
} else {
return false;
}
return false;
}
}
bool date::isLeapYear(int year) {
return ((year % 4) == 0);
}
and Finally, the test program
#include <iostream>
using std::cout;
using std::endl;
#include "date.h"
int main() {
date d;
cout << "1/1/1988 before 3/5/1990 [" << d.before("1/1/1988", "3/5/1990")
<< "]\n1/1/1988 before 1/1/1970 [" << d.before("a/a/1988", "1/1/1970")
<<"]\n";
cout << "years between 1/1/1988 and 1/1/1998 ["
<< d.yearsBetween("1/1/1988", "1/1/1998") << "]\n";
cout << "is 1/1/1988 valid [" << d.isValid("1/1/1988") << "]\n"
<< "is 2/13/1988 valid [" << d.isValid("2/13/1988") << "]\n"
<< "is 32/12/1988 valid [" << d.isValid("32/12/1988") << "]\n";
cout << "blerg\n";
}
I've left in some extraneous cout statements, which I've been using to try and locate the error.
I thank you in advance.
Change:
private:
int days[];
to:
private:
int days[12];
The problem is that you never actually initialize the days field in the type date. This means that when you are setting the values in the constructor you are accessing uninitialized memory.
You need to explicitly initialize the days value in some way. The easiest fix is to use a vector for the type or to hard code the size of the array to 12.
private:
int days[12];
Or
private:
std:vector<int> days;
...
date::date() {
days.push_back(31);
days.push_back(28);
...
}
You don't say which compiler you are using, but if I compile this code using g++ with the -Wall and -pedantic flags:
struct S {
int a[];
};
int main() {
S s;
}
I get the warning message:
warning: ISO C++ forbids zero-size array 'a'
The moral is that you should always compile using as many compiler warnings as possible - it can save you mountains of time and result in more correct code.
int days[];
This is a non-standard extension. You must specify a size for the array, such as:
static const MonthCount = 12;
int days[MonthCount];
To actually have an array to use. Otherwise you have a "zero-sized array" (not standard!). Your program is tromping over memory every time you use any element of your current array.
I agree with the previous answers to this question, but I would add the rationale for their correctness:
Segmentation faults are caused whenever you attempt to access memory you are not allowed to access.
http://en.wikipedia.org/wiki/Segmentation_fault
You were not allowed to access "days[0]" through days "[11]" because the computer had not given the "days[]" variable that you declared enough memory to hold any elements, thus when you tried to access said elements, it threw a segfault.
Any variables not declared with the "new" operator are placed on the "stack," which is a contiguous chunk of memory the computer has sectioned away for use by the program. In order to keep everything stored in the stack contiguous, the computer will only give exactly the amount memory you require for you to use whenever you request it, so that if you request to create an int, for example, it will only give you enough memory to store that single int.
When you wrote the line int days[]; the computer attempted to evaluate how much memory it would require, assessed it as an empty array, and gave you enough memory to store said empty array. Because the computer did not give your array any extra space beyond what was needed for an empty array, it knew that the memory you tried to access in that array had not been assigned to it, so it threw a segmentation fault and crashed.
If you have not yet learned about the "stack" and "heap" in your computer science class, then sorry if this is a bit overwhelming, but I perhaps overcomplicated things, and I think you likely soon will.