error: expected unqualified-id before ‘.’ token //(struct) - c++

I need to make a program that gets a fraction from the user and then simplifies it.
I know how to do it and have done most of the code but I keep getting this error "error: expected unqualified-id before ‘.’ token".
I have declared a struct called ReducedForm which holds the simplified numerator and denominator, now what Im trying to do is send the simplified values to this struct.
Here is my code;
In Rational.h;
#ifndef RATIONAL_H
#define RATIONAL_H
using namespace std;
struct ReducedForm
{
int iSimplifiedNumerator;
int iSimplifiedDenominator;
};
//I have a class here for the other stuff in the program
#endif
In Rational.cpp;
#include <iostream>
#include "rational.h"
using namespace std;
void Rational :: SetToReducedForm(int iNumerator, int iDenominator)
{
int iGreatCommDivisor = 0;
iGreatCommDivisor = GCD(iNumerator, iDenominator);
//The next 2 lines is where i get the error
ReducedForm.iSimplifiedNumerator = iNumerator/iGreatCommDivisor;
ReducedForm.iSimplifiedDenominator = iDenominator/iGreatCommDivisor;
};

You are trying to access the struct statically with a . instead of ::, nor are its members static. Either instantiate ReducedForm:
ReducedForm rf;
rf.iSimplifiedNumerator = 5;
or change the members to static like this:
struct ReducedForm
{
static int iSimplifiedNumerator;
static int iSimplifiedDenominator;
};
In the latter case, you must access the members with :: instead of . I highly doubt however that the latter is what you are going for ;)

The struct's name is ReducedForm; you need to make an object (instance of the struct or class) and use that. Do this:
ReducedForm MyReducedForm;
MyReducedForm.iSimplifiedNumerator = iNumerator/iGreatCommDivisor;
MyReducedForm.iSimplifiedDenominator = iDenominator/iGreatCommDivisor;

ReducedForm is a type, so you cannot say
ReducedForm.iSimplifiedNumerator = iNumerator/iGreatCommDivisor;
You can only use the . operator on an instance:
ReducedForm rf;
rf.iSimplifiedNumerator = iNumerator/iGreatCommDivisor;

Related

Declare static arrays in a struct right in C++

I tried to declare static array:
#include <iostream>
#include <string.h>
using namespace std;
struct tagData{
static string tags[];
};
int main(){
tagData::tags[3];
tagData::tags[0] = "default";
tagData::tags[1] = "player";
tagData::tags[2] = "enemy";
return 0;
}
But as the result an error occurred:
*Path*\cczPqyfY.o:main.cpp:(.text+0x1e): undefined reference to `tagData::tags[abi:cxx11]'
*Path*\cczPqyfY.o:main.cpp:(.text+0x32): undefined reference to `tagData::tags[abi:cxx11]'
*Path*\cczPqyfY.o:main.cpp:(.text+0x46): undefined reference to `tagData::tags[abi:cxx11]'
collect2.exe: error: ld returned 1 exit status
I was looking for some info about how to declare static arrays in structs, but couldn't.
Can anybody show me an example or help me in another way?
P.S.
I tried to compile this code with GCC version 8.1.0;
struct tagData{
static string tags[];
};
This static class member must be defined in global scope, and not as a local variable in a function like main:
string tagData::tags[3];
And now, once the formalities are taken care of, you can manually access its class members, in main or any other function:
int main(){
tagData::tags[0] = "default";
tagData::tags[1] = "player";
tagData::tags[2] = "enemy";
return 0;
}
However, if the goal is to initialize the array there's an even better way. Just initialize it as part of its definition:
string tagData::tags[3]={"default", "player", "enemy"};
Note: when defining static class member, you should always keep in mind the static initialization order fiasco.

Why I can't use my class without parenthesis?(in C++)

//this is main.cpp
#include <iostream>
#include "Cook.hpp"
using namespace std;
int main(void){
int l = Cook.get_life();
}
//this is cook.hpp
#ifndef HUNTER_H
#define HUNTER_H
class Cook
{
public:
int get_life(void);
private:
int life;
};
#endif
//this is cook.cpp
#include "Cook.hpp"
int Cook::get_life(void)
{
life=0;
return life;
}
They are all in same folder. And I get compile error when I run main.cpp. And Xcode recommended to use Cook().get_life() instead of Cook.get_life(). Can you explain why? I thought I should use Cook.get_life.
I use Xcode.
First you have to declare variable with type of you class (instance) and then you can use it, But classes has static functions too, that mean you can use function without declare instance of it first but in that you can't use member variable of class, Reading more about concept of classes and more ...
get_life is not a static function, you have to call it on an instance of your class Cook, and that's exactly what Cook() does. If you want to call get_life without an instance of Cook, you should declare your function this way :
static int get_life(void);
And then call it like that :
Cook::get_life();
The thing is you can't use class attributes from static member functions, so instead you need to instantiate your class Cook before calling your member function.
Cook c = Cook(); // Cook().get_life() works to, but you don't keep your newly created object
c.get_life();

Problem with creation of instances of classes inside another class

I'm trying to create a class from within a class but I'm now very confused about how can that be done. I've tried for hours and hava had no luck, and my beginner level in c++ has limited me also a bit.
I've been using this link for reference with no success :/:
Creating instance in an another class of an object
This is my code:
Big class Sensor.h:
#ifndef SENSOR_H
#define SENSOR_H
#include "Dummy_Sensor.h"
#include "Lovato_DMG610.h"
class Sensor{
public:
double last10Vals [10];
char id[2];
Lovato_DMG610 dataSource(2);
Sensor(unsigned char dataSize){
}
int getSensorData ()
{
return 0;
}
private:
unsigned char dataSize;
};
#endif
My smaller class Lovato_DMG610.h:
#ifndef _KERN_LOVATO_DMG610
#define _KERN_LOVATO_DMG610
#include <Arduino.h>
//using namespace std;
class Lovato_DMG610{
public:
double variable = 0;
Lovato_DMG610(uint8_t pinToConnect)
{
_pinToConnect=pinToConnect;
}
private:
uint8_t _pinToConnect;
};
#endif
I've been getting an error related to the first file:
Sensor.h:10: error: 'Lovato_DMG610' does not name a type
Lovato_DMG610 dataSource(2);
My question for you guys would be:
How could i include the Lovato class in order to avoid this error?
How should the Lovato parameters should be set from Sensor class?
(this question is related to an error I'm also getting "Sensor.h:10: error: expected identifier before numeric constant
Lovato_DMG610 dataSource(2);")
I was using the code: using namespace std; before all class declarations and I get it is not a good practice (https://www.quora.com/What-does-using-namespace-std-mean-in-C++). Nevertheless, I would like to ask you if you could advise me whether this should be used in the scope of any of these headers.
Main program will keep an array of Sensor objects in which i want to make queries to different sensors. The only include in my Header.h is Sensors.h.
Thank you!
Update: After correcting the initialization as proposed by vll the constructor is ok (question 2 is resolved) but the same 'Lovato_DMG610' does not name a type' in Sensor.h error appears every time.
Parameters should be set in the constructor:
Lovato_DMG610 dataSource;
Sensor(unsigned char dataSize) : dataSource(2)
{}

Error request for member getName which is of non-class type 'char'

I'm trying to make a program involving files assign2.cpp, Player.h, Player.cpp, Team.h, Team.cpp which reads data from a txt file on player info (like hits, atBat, position, name and number) and displays it out into assign2.cpp. assign2.cpp is what contains int main() and is suppose to contain very little code because relies on the other files to do the work.
The error:
request for member getName which is of non-class type ‘char’...
Please help, I've been trying to find the issue and can never do so. The compilation failure :
In file included from Team.cpp:1:0:
Team.h:34:11: warning: extra tokens at end of #endif directive [enabled by default]
Team.cpp: In constructor ‘Team::Team()’:
Team.cpp:15:5: warning: unused variable ‘numPlayers’ [-Wunused-variable]
Team.cpp: In member function ‘void Team::sortByName()’:
Team.cpp:49:56: error: request for member ‘getName’ in ‘((Team*)this
-> Team::playerObject[(j + -1)]’, which is of non-class type ‘char’
Team.cpp:49:74: error: request for member ‘getName’ in ‘bucket’, which is of non-class type ‘int’
Team.cpp: In member function ‘void Team::print()’:
Team.cpp:63:18: error: request for member ‘print’ in ‘((Team*)this)- >Team::playerObject[i]’, which is of non-class type ‘char’
make: *** [Team.o] Error 1
Team.h
#ifndef TEAM_H
#define TEAM_H
#include "Player.h"
class Team
{
private:
char playerObject[40];
int numPlayers; // specifies the number of Player objects
// actually stored in the array
void readPlayerData();
void sortByName();
public:
Team();
Team(char*);
void print();
};
#endif / *Team.h* /
Team.cpp
#include "Team.h"
#include <cstring>
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <cstdlib>
using namespace std;
Team::Team()
{
strcpy (playerObject,"");
int numPlayers = 0;
}
Team::Team(char* newPlayerObject)
{
strncpy(playerObject, newPlayerObject, 40);
readPlayerData();
}
void Team::readPlayerData()
{
ifstream inFile;
inFile.open("gamestats.txt");
if (!inFile){
cout << "Error, couldn't open file";
exit(1);
}
inFile.read((char*) this, sizeof(Team));
inFile.close();
}
void Team::sortByName()
{
int i, j;
int bucket;
for (i = 1; i < numPlayers; i++)
{
bucket = playerObject[i];
for (j = i; (j > 0) && (strcmp(playerObject[j-1].getName(), bucket.getName()) > 0); j--)
playerObject[j] = playerObject[j-1];
playerObject[j] = bucket;
}
}
Player.h (incase anyone needs it)
#ifndef PLAYER_H
#define PLAYER_H
class Player
{
// Data members and method prototypes for the Player class go here
private:
int number;
char name[26];
char position[3];
int hits;
int atBats;
double battingAverage;
public:
Player();
Player(int, char*, char*, int, int);
char* getName();
char* getPosition();
int getNumber();
int getHits();
int getAtBats();
double getBattingAverage();
void print();
void setAtBats(int);
void setHits(int);
};
#endif
I'm very stuck, Thanks in advance.
In the Team constructor on this line
playerObject = newPlayerObject;
you're trying to assign a value of type char* to a member of type char[40], which doesn't work, since they are two different types. In any case, you probably would need to copy the data from the input instead of just trying to hold the pointer internally. Something like
strncpy(playerObject, newPlayerObject, 40);
Generally, you will always be able to assign a char[N] to a char*, but not the other way around, but that's just because C++ will automatically convert the char[N] to a char*, they are still different types.
Your declaration is:
char playerObject[40];
And your constructor reads:
Team::Team(char* newPlayerObject)
{
playerObject = newPlayerObject;
The error message you referenced in the title of this question obviously comes from here, and it is self explanatory. An array and a pointer are two completely different, incompatible types, when it comes to this kind of an assignment.
What you need to do depends entirely on what you expect to happen, and what your specifications are.
A) You could be trying to initialize the array from the character pointer, in which case you'll probably want to use strcpy(). Of course, you have to make sure that the string, including the null byte terminator, does not exceed 40 bytes, otherwise this will be undefined behavior.
Incidently, this is what you did in your default constructor:
Team::Team()
{
strcpy (playerObject,"");
}
B) Or, your playerObject class member should, perhaps, be a char * instead, and should be either assigned, just like that, or perhaps strdup()ed. In which case your default constructor will probably need to do the same.
Whichever one is the right answer for you depends entirely on your requirements, that you will have to figure out yourself.

Using namespace for static class members

Can someone explain why the following code does not work? I cannot find any resources explaining the how namespaces, classes and identifiers fit together. When you do my_class::my_member, the my_class:: part is not a namespace? What is it?
#include <iostream>
class my_class {
public:
static void my_member() {
std::cout << "worked" << std::endl;
}
};
int main() {
using namespace my_class; // error: 'my_class' is not a namespace-name
my_member(); // error: 'my_member' was not declared in this scope
my_class::my_member(); // works
}
As a more general question: is there a way I can reference static class members without doing the my_class:: namespace/ identifier/ whatever each time?
Instead of
my_class::my_member_1
my_class::my_member_2
I just want
my_member_1
my_member_2
Is this possible? Thank you.
Is this possible?
Yes, indirectly. If you create a method that operates in my_class's scope, then you can get the behavior you want.
#include <iostream>
class my_class {
public:
static void my_member() {
std::cout << "worked" << std::endl;
}
static int my_main();
};
int my_class::my_main() {
my_member(); // no error
my_class::my_member(); // works too
return EXIT_SUCCESS;
}
int main() {
my_class::my_main();
}
my_class is not a namespace, it is a class name (a type). Therefore, you cannot use using namespace with my_class.
If you want to use my_member_1 without prefixing the class name, create a global wrapper function.
void my_member_1() {
my_class::my_member_1();
}
When you call a static function like this :
my_class::my_member();
You are refering to the class definition to find the static function. A static function will be the same for every instance of your class. You cannot access the static function either by simply calling the function name, or by creating an instance of the class to call the static function.
If you want to call directly the static function without writing down the class definition, you could do something like :
#define my_member_1 my_class::my_member_1()
#define my_member_2 my_class::my_member_2()
...
After that you could simply call my_member_1 to execute your static function, but that could get confusing on a large scale program. My advice is to keep using the class definition so you know exactly what function you are calling.