I wrote a class. And when I specified the function, it failed - c++

class equation
{
public :
int k;
int l;
int t;
float x1_value;
float x2_value;
float b1 = sqrt(l^2 -4*k*t);
float equation1;
equation();
~equation();
};
float void equation::equation1() {
if (b1 == 0)
{
float x1_value = -l/2*k;
cout << " joongen. " <<x1_value <<endl;
}
else if (b1 > 0)
{
float x1_value = ((-l + sqrt(b1) / (2*k));
float x2_value = ((-l - sqrt(b1) / (2*k));
cout << "x is 2"<< x1_value < " x 2 is "<< x2_value <<endl;
}
else
{
cout <<"imagine number ."<<endl;
}
return (0);
};
The code produces this error:
error: two or more data types in declaration of 'equation1'
float void equation::equation1() {
^

I can make out two problems.
First you define equation1 as a member variable with type float. You might want to change that into a function declaration.
// ...
float equation1();
// ...
The second problem is pointed out in the comments. If you implement your function, you should only use one return type. As I can only guess, what return type you would really want, I take float, since it is in your faulty function declaration.
// ...
float equation::equation1() {
// ...
}
// ...
One extra thing, that disturbs me every time I see someone who is new with C++. Please, please, please, don't use using namespace std;. I assume you do so, because of the missing std::. You open up an fastly huge namespace. You may end up defining a function, with the same name and parameters and encounter a very cryptic error, which is nearly impossible to figure out.

Related

Condensing functions to go two ways in C++

Apparently, I should be able to condense these six functions into three simpler functions that go two ways, using bool logic, but I have no idea where to start!
void footToMeter(int inputfeet) {
double outputMeter = ((inputfeet) / (3.281));
cout << outputMeter;
}
void meterToFoot(int inputmeter) {
double outputFoot = ((inputmeter)*(3.281));
cout << outputFoot;
}
void CtoF(int inputC) {
double outputF = 32 + (inputC*(9.0 / 5.0));
cout << outputF;
}
void FtoC(int inputF) {
double outputC = (5.0 / 9)*(inputF - 32);
cout << outputC;
}
void cMtocF(int inputcM) {
double outputcF = ((inputcM)*(35.315));
cout << outputcF;
}
void cFtocM(int inputcF) {
double outputcM = ((inputcF) / (35.315));
cout << outputcM;
}
One approach would be to add an extra parameter for each function to determine which direction you want to convert.
Example:
void lengthConversion(int inputLength, bool toFeet)
{
double output;
if (toFeet)
output = inputLength * 3.281;
else
output = inputLength / 3.281
cout << output;
}
#forthe has a point though - enum would make it a bit nicer.
To make it into 3 simpler functions. First try and bundle up the similarities between the current functions:
// Put the foot to meter and meter to foot functions into one, with 2 extra boolean values.
void fAndMConversion(int measurement , bool footToMeter , bool meterToFoot) {
if(footToMeter){
double fTm = ((measurement) / (3.281));
cout << fTm;
}
if(meterToFoot){
double mTf = ((measurement)*(3.281));
cout << mTf;
}
}
These are the first two functions. This also allows us to get foot to meter and meter to foot conversion in one call to the function: fAndMConversion(11 , true , true). You can bundle it up even further into a conversions() function with 7 args in total, 6 being booleans.

Overloading c++ operators int/float(..)

I'm working on operators in C++ now, but i have one problem. Well I'm trying to overloard int/float operators, I have 2 variables in class
class Zespolona{
public:
float re;
float im;
}
I've done all of my operators but when i do
operator int const(){
this->re = (int)this->re;
this->im = (int)this->im;
return *this;
}
then it gets an infinite loop.
My main
int main(){
Zespolona z1;
z1.re = 1.2;
z1.im = 34.9;
z1 = (int)z1;
cout << z1 << endl;
}
What can i do, to get int of two of those variables?
I am not completely sure what you are trying to achieve. I am guessing one of the following two possibilities:
1) Covert the two floats of your class (re, im) into integers:
This is rather simple. Since the two members are public you can access them directly:
#include <iostream>
int main()
{
Zespolona Z1;
Z1.re = 1.2;
Z1.im = 34.9;
std::cout << "Re: " << (int) Z1.re << std::endl;
std::cout << "Im: " << (int) Z1.im << std::endl;
return 0;
}
The output of this program should be:
Re: 1
Im: 34
Note: When you convert a float to an integer everything after the decimal dot is omitted (at least that is the behavior using g++ under Ubuntu).
If you want the two floats to be private or protected you would have to create methods like int GetRe() and int GetIm().
2) Convert the two floats of your class (re, im) into one integer using the integer conversion operator operator int const(). This operator has to return exactly one int. For the following example I decided to return the absolute value (magnitude) of the complex number (since your members are called re and im I am guessing the class is used for complex numbers):
class Zespolona
{
public:
float re;
float im;
operator int const()
{
return (int) sqrt(re*re + im*im);
}
};
int main()
{
Zespolona Z1;
Z1.re = 1.2;
Z1.im = 34.9;
std::cout << "Z1: " << (int) Z1 << std::endl;
return 0;
}
The output should now be:
Z1: 34
Note: Again the correct (float) result 34.92... is converted into the integer 34.
The code you mentioned in your questions returns a reference to your class Zespolona when you try to convert it into int. Thus, the compiler again tries to convert that reference into an int. But all it gets is again a reference to Zespolona, and so on. Hence, you get an infinite loop.

C++ Undeclared Identifier on Object creation

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

Returning Arrays from functions in C++

Good day :) I am working on a code for obtaining pitch, yaw and roll angles from an Accelerometer and a Gyroscope. To create a cleaner looking code that is easy to follow, I resorted to creating two different functions. One for the gyroscope that calculates the Pitch Yaw and Roll, and another for the accelerometer which also does the same thing.
float *readGyro(){
/*get data from sensor here*/
float gyroAngles[4]={gyroPitch,gyroRoll,gyroYaw};
float* gyroPRY=gyroAngles;
return gyroPRY;
}
float *readAccel(){
/*get data from sensor here*/
float accelAngles[4]={accelPitch,accelRoll,accelYaw};
float* accelPRY=accelAngles;
return accelPRY;
}
As you can see above, I stored the outputs of the functions into an array to be passed onto the main function. Basically the pointer is passed. However upon accessing the values from the pointer passed, constant junk values (not changing as I move the IMU) were printed instead (eg. 2.38221e-44 and -3.84146e-06). I checked the output of the functions for the gyro and the accelerometer by printing the values within those functions and they were fine.
int main(void){
float *accelData;
float *gyroData;
while(1){
accelData=readGyro();
gyroData=readAccel();
float accelPitch=*(accelData);
float accelRoll=*(accelData+1);
float accelYaw=*(accelData+2);
float gyroPitch=*(gyroData);
float gyroRoll=*(gyroData+1);
float gyroYaw=*(gyroData+2);
cout << "AccelPitch=" << accelPitch <<endl;
cout << "AccelRoll=" << accelRoll <<endl;
cout << "AccelYaw=" << accelYaw <<endl;
cout << "GyroPitch=" << gyroPitch <<endl;
cout << "GyroRoll=" << gyroRoll <<endl;
cout << "GyroYaw=" << gyroYaw <<endl;
}
}
I could not find what I did wrong with my code. Prior to this I consulted many references. However I still couldn't solve it. Your help would be very appreciated :)
C++'s built-in arrays are inherited from C, and don't necessarily work the way most people expect. Let's say you have a function like this:
float* get_vec() {
float vec[3] = { 1.0f, 2.0f, 3.0f };
return vec;
}
what this actually does is return the address of the stack-allocated variable vec; unfortunately vec will go out of scope when the function ends, and the returned address will be meaningless.
The way round this is to wrap the array up in a struct, which can be returned by value. You can either define your own, or use std::array from the C++ standard library, like so:
std::array<float, 3> get_vec() {
std::array<float, 3> vec = { 1.0f, 2.0f, 3.0f };
return vec;
}
What you are doing is returning the address of the array that is local to the function which gets destroyed when the function exits.
If you want an array for indexing reasons then I would recommend using std::array.
std::array<float, 3> readGyro() {
/*get data from sensor here*/
return {gyroPitch, gyroRoll, gyroYaw};
}
But better would be to use a struct like this.
struct angles
{
float pitch;
float roll;
float yaw;
};
angles readGyro() {
/*get data from sensor here*/
return {gyroPitch, gyroRoll, gyroYaw};
}
What you are doing will never work, as you are returning a pointer onto the stack of readGyro and readAccel. When those functions exit, that part of the stack is reclaimed and you are left with undefined behaviour.
One way would be to allocate the array and return it, but then you burden yourself with having to delete that allocation as well.
You could create 2 structs for the required parameters and pass them into your functions. That way the functions can write somewhere that will persist after they return.
e.g.
#include <iostream>
using std::cout;
using std::endl;
struct gyro_data_t
{
float pitch;
float roll;
float yaw;
};
struct accel_data_t
{
float pitch;
float roll;
float yaw;
};
void readGyro(gyro_data_t* gd)
{
/*get data from sensor here*/
gd->pitch = 1.0f;
gd->roll = 1.1f;
gd->yaw = 1.2f;
}
void readAccel(accel_data_t* ad)
{
/*get data from sensor here*/
ad->pitch = 1.0f;
ad->roll = 1.1f;
ad->yaw = 1.2f;
}
int main(void)
{
accel_data_t accelData;
gyro_data_t gyroData;
while(1)
{
readGyro(&gyroData);
readAccel(&accelData);
cout << "AccelPitch=" << accelData.pitch << endl;
cout << "AccelRoll=" << accelData.roll << endl;
cout << "AccelYaw=" << accelData.yaw << endl;
cout << "GyroPitch=" << gyroData.pitch << endl;
cout << "GyroRoll=" << gyroData.roll << endl;
cout << "GyroYaw=" << gyroData.yaw << endl;
}
}
Note how this is also more readable than your example as it names each variable explicitly, rather than expressing them as offsets from the returned value. The assignment to new variables to allow you to comprehend what the values mean is no longer required.
The two structs are actually identical and so could be condensed into one general struct if required.
Wrap array as a struct to return by value
While copying the array as data-member, the array elements will be copied one by one instead of copying the decayed pointer. This avoids returning the address of local variable.
struct float3{
float fs[3];
};
float3 readGyro(){
float3 f3 = {};
f3.fs[0] = gyroPitch;
f3.fs[1] = gyroRoll;
f3.fs[2] = gyroYaw;
return f3;
}
But using the std::array<float, 3> as other answers said is much appropriate. You don't need to invent another wheel.
Get the result via pass by reference
If you like get result through parameters, use reference instead of pointer to avoid lost the size information (decayed to pointer). This also ensures only type float[3] is passed.
void readGyro(float (&fs)[3])
{
fs[0] = gyroPitch;
fs[1] = gyroRoll;
fs[2] = gyroYaw;
}

C++ - Method Override Isn't Expressed as Expected

I have a Base class Point (representing a 2D point in space) that is non-thread-safe for move operations; so I defined an inherited class LockedPoint that overrides 2 methods in the base class: moveTo and moveBy:
void Point::moveTo(float xPos, float yPos) {
x = xPos;
y = yPos;
}
void Point::moveBy(float xOff, float yOff) {
x += xOff;
y += yOff;
}
void LockedPoint::moveTo(float xPos, float yPos) {
MutGuard m(lock);
x = xPos;
y = yPos;
}
void LockedPoint::moveBy(float xOff, float yOff) {
MutGuard m(lock);
x += xOff;
y += yOff;
}
( where x and y = private member variables,
lock = a private mutex, and
MutGuard = typedef lock_guard<mutex> )
To visually see the problem with the "unlocked" Point, I wrote up a test routine:
void sleepForMS(long ms) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
void messWithPoint(Point& p, int type) {
float n = 1;
if (type) n *= -1;
for (long i = 0; i < 10000; i++) {
p.moveBy(n, n);
sleepForMS(rand() % (type ? 2 : 3));
if (i % 500 == 0)
std::cout << i << ":\t" << p << std::endl;
}
}
int main(int argc, char* argv[]) {
using namespace std;
Point p;
thread t1(messWithPoint, std::ref(p), 0);
sleepForMS(33);
thread t2(messWithPoint, std::ref(p), 1);
cout << "Started\n";
t1.join();
t2.join();
cout << p << endl;
}
With a Point, the resulting p is "corrupted", as expected (it should equal (0,0) by the end, and it doesn't). If I change p to a LockedPoint though, the base version of moveBy is still called (verified by print debugging).
I read up on method "overriding" (apparently more correctly called "method hiding"), and from what I understand, if the overriding method has the same signature as the base method, it hides the base version, and is called instead. Why then is the base method being called despite the 2 having the same signature? The only thing I can think of is because I'm specifying Point in messWithPoint's argument list, it's taking that literally and calling Point's version. If I change the signature to void messWithPoint(LockedPoint& p, int type), the resulting LockedPoint is (0,0), as expected. Shouldn't it "see" that the passed LockedPoint overrides the used method, and use the "least hidden" version?
If that's not how it works, is there a way to specify taking the base class, but having it use any available overridden versions?
The member functions are not virtual, so the functions in the class known at compile time are used.
However, for a simple class such as point, using virtual member functions or providing automatic mutual exclusion goes against the C++ idea of not paying for what you don't use.
Just copy points.