Error with template specialization that relates to static members [duplicate] - c++

This program has the user input name/age pairs and then outputs them, using a class.
Here is the code.
#include "std_lib_facilities.h"
class Name_pairs
{
public:
bool test();
void read_names();
void read_ages();
void print();
private:
vector<string>names;
vector<double>ages;
string name;
double age;
};
void Name_pairs::read_names()
{
cout << "Enter name: ";
cin >> name;
names.push_back(name);
cout << endl;
}
void Name_pairs::read_ages()
{
cout << "Enter corresponding age: ";
cin >> age;
ages.push_back(age);
cout << endl;
}
void Name_pairs::print()
{
for(int i = 0; i < names.size() && i < ages.size(); ++i)
cout << names[i] << " , " << ages[i] << endl;
}
bool Name_pairs::test()
{
int i = 0;
if(ages[i] == 0 || names[i] == "0") return false;
else{
++i;
return true;}
}
int main()
{
cout << "Enter names and ages. Use 0 to cancel.\n";
while(Name_pairs::test())
{
Name_pairs::read_names();
Name_pairs::read_ages();
}
Name_pairs::print();
keep_window_open();
}
However, in int main() when I'm trying to call the functions I get "cannot call 'whatever name is' function without object." I'm guessing this is because it's looking for something like variable.test or variable.read_names. How should I go about fixing this?

You need to instantiate an object in order to call its member functions. The member functions need an object to operate on; they can't just be used on their own. The main() function could, for example, look like this:
int main()
{
Name_pairs np;
cout << "Enter names and ages. Use 0 to cancel.\n";
while(np.test())
{
np.read_names();
np.read_ages();
}
np.print();
keep_window_open();
}

If you want to call them like that, you should declare them static.

just add static keyword at the starting of the function return type..
and then you can access the member function of the class without object:)
for ex:
static void Name_pairs::read_names()
{
cout << "Enter name: ";
cin >> name;
names.push_back(name);
cout << endl;
}

You are right - you declared a new use defined type (Name_pairs) and you need variable of that type to use it.
The code should go like this:
Name_pairs np;
np.read_names()

Related

Printing value in void to other void

I'm trying to print a value found in the "getvalue" void in the "show" void. I get an error:
error: 'Students' was not declared in this scope
#include <iostream>
using namespace std;
int studentNumber=0;
int testNumber=0;
struct Student
{
string name,grade;
int studentNo,*testResults;
double average;
};
void getValue()
{
cout << "Enter the number of students: ";
cin >> studentNumber;
cout << "Enter the number of tests: ";
cin >> testNumber;
Student* Students = new Student[studentNumber];
for(int i=0; i< studentNumber; i++)
{
cout<< "\n" << "Enter the name of the " << i+1 << ". student: ";
cin >> Students[i].name;
cout<< "\n" << "Enter the number of the " << i+1 << ". student: ";
cin >> Students[i].studentNo;
Students[i].testResults = new int[testNumber];
for(int z=0; z<testNumber; z++)
{
cout<< "\n" << "Enter the " << z+1 << ". exam grade of the " << i+1 << ". student: " ;
cin >> Students[i].testResults[z];
}
}
}
void show()
{
for(int i=0; i < studentNumber; i++)
{
cout<< "\n" << Students[i].name;
cout<< "\n" << Students[i].studentNo;
for(int z=0; z<testNumber; z++)
{
cout<< "\n" <<Students[i].testResults[z];
}
}
}
int main()
{
getValue();
show();
}
I'm trying to show the obtained values ​​in another void called "show" but failed. (The general structure of the code that must be in a different void must be another void named "show" in my homework)
You have to pass the value.
It can be done via reference:
// omit
void getValue(Student*& Students) // add reference argument
{
cout << "Enter the number of students: ";
cin >> studentNumber;
cout << "Enter the number of tests: ";
cin >> testNumber;
// don't declare here and use the arugment
Students = new Student[studentNumber];
// omit
}
void show(Student* Students) // add argument (need not be reference)
{
// omit
}
int main()
{
// add variable for arguments and use that
Student* s;
getValue(s);
show(s);
}
Or via global variable:
// omit
// declare variable here (as global)
static Student* Students;
void getValue()
{
cout << "Enter the number of students: ";
cin >> studentNumber;
cout << "Enter the number of tests: ";
cin >> testNumber;
// don't declare here and use the global variable
Students = new Student[studentNumber];
// omit
}
void show()
{
// omit
}
int main()
{
getValue();
show();
}
Instead of raw arrays, it might be good to use std::vector<Student>. It'd be easy to replace:
Student* Students = new Student[studentNumber];
with:
#include <vector>
...
std::vector<Student> Students(studentNumber);
(pretty much everything else should be the same) and then for the actual error you're seeing, since the Students array only exists inside the scope of the getValue() function, you'll need to return it so that show() can the array too. Consider changing the code to something like (assuming you're using the vector):
std::vector<Student> getValue() {
...
return Students;
}
void show(std::vector<Student> Students)
...
}
int main() {
auto Students = getValue();
show(Students);
}

Qt C++ cannot call member function '~~ const' without object [duplicate]

This program has the user input name/age pairs and then outputs them, using a class.
Here is the code.
#include "std_lib_facilities.h"
class Name_pairs
{
public:
bool test();
void read_names();
void read_ages();
void print();
private:
vector<string>names;
vector<double>ages;
string name;
double age;
};
void Name_pairs::read_names()
{
cout << "Enter name: ";
cin >> name;
names.push_back(name);
cout << endl;
}
void Name_pairs::read_ages()
{
cout << "Enter corresponding age: ";
cin >> age;
ages.push_back(age);
cout << endl;
}
void Name_pairs::print()
{
for(int i = 0; i < names.size() && i < ages.size(); ++i)
cout << names[i] << " , " << ages[i] << endl;
}
bool Name_pairs::test()
{
int i = 0;
if(ages[i] == 0 || names[i] == "0") return false;
else{
++i;
return true;}
}
int main()
{
cout << "Enter names and ages. Use 0 to cancel.\n";
while(Name_pairs::test())
{
Name_pairs::read_names();
Name_pairs::read_ages();
}
Name_pairs::print();
keep_window_open();
}
However, in int main() when I'm trying to call the functions I get "cannot call 'whatever name is' function without object." I'm guessing this is because it's looking for something like variable.test or variable.read_names. How should I go about fixing this?
You need to instantiate an object in order to call its member functions. The member functions need an object to operate on; they can't just be used on their own. The main() function could, for example, look like this:
int main()
{
Name_pairs np;
cout << "Enter names and ages. Use 0 to cancel.\n";
while(np.test())
{
np.read_names();
np.read_ages();
}
np.print();
keep_window_open();
}
If you want to call them like that, you should declare them static.
just add static keyword at the starting of the function return type..
and then you can access the member function of the class without object:)
for ex:
static void Name_pairs::read_names()
{
cout << "Enter name: ";
cin >> name;
names.push_back(name);
cout << endl;
}
You are right - you declared a new use defined type (Name_pairs) and you need variable of that type to use it.
The code should go like this:
Name_pairs np;
np.read_names()

Error "identifier not declared in this scope" - C++

C++ beginner here. So I have several functions in which I am trying to pass an element of array of pointers (which contains structures (records)). I'm having trouble doing this and I'm pretty stuck and frustrated. I'm very new to pointers and memory so go easy on me. I keep getting errors when I try to pass the specific structure element into the function. (BTW: The functions are declared in a header file)
What can I do to fix/change this and make it work? Thank you for the help, it is very much appreciated.
The error I get:
'changeAssignmentGradeForStudent' was not declared in this scope
Code:
Structure student:
typedef struct
{
char firstName[50];
char lastName[50];
char studentNumber[10];
char NSID[10];
float assignments[10];
float midterm;
float final;
} Student;
void useFunctions(int recordNum)
{
// array of 10 student references
Student *students[recordNum];
// values received from the user
for (int i = 0; i < recordNum; i++)
{
cout << "Student " << i + 1 << ": " << endl;
students[i] = readStudentRecordFromConsole();
}
cout << "Would you like to make any changes to any student records? (N or Y)" << endl;
cin >> answer;
if (answer == 'N')
{
return;
}
else
{
cout << "Which student?" << endl;
cin >> student;
students[student - 1] = gradeChanges(*students[student - 1], recordNum, student);
}
}
Student *gradeChanges(Student *s, int recordNum, int student)
{
Student *changedStudent = s;
int gradeChange, aNum;
cout << "assignment number to change?" << endl;
cin >> aNum;
cout << "assignment to change?" << endl;
cin >> gradeChange;
changeAssignmentGradeForStudent(changedStudent, aNum, gradeChange); // where the errors are
return changedStudent;
}
void changeAssignmentGradeForStudent(Student *s, int a, int g)
{
if (s != NULL)
{
s->assignments[a] += g;
}
}
PS: Sorry if my code is not formatted correctly. If it isn't, feel free to edit it, thank you.
The function changeAssignmentGradeForStudent was not declared or defined before it was used, so the compiler doesn't know about it yet. You can either move the function definition up before useFunctions() or declare it at the top of the file like this:
void changeAssignmentGradeForStudent(Student*, int, int);
The compiler needs to see a declaration of your functions before these are referred to. You have to put that declaration before you call a function like this:
// This is the (forward) declaration:
void changeAssignmentGradeForStudent(Student* s, int a, int g);
Student * gradeChanges(Student* s, int recordNum, int student) {
Student *changedStudent = s;
int gradeChange, aNum;
cout << "assignment number to change?" << endl;
cin >> aNum;
cout << "assignment to change?" << endl;
cin >> gradeChange;
changeAssignmentGradeForStudent(changedStudent, aNum, gradeChange); // where the errors are
return changedStudent;
}
// This is the definition:
void changeAssignmentGradeForStudent(Student* s, int a, int g) {
if (s != NULL) {
s->assignments[a] += g;
}
}

I have trouble with some pointers, access location failed at the end of debugging

// header.h
#include <iostream>
#include <list>
#include <fstream>
using namespace std;
class Biblioteca
{
public:
Biblioteca();
void closeFile();
bool chose();
ofstream Intrare;
ofstream Memorare;
};
class Publicatii:public virtual Biblioteca
{
public:
string retTitlu();
string retEditura();
string retAutor();
int retAn();
int retTiraj();
int retNumar();
int retFrecventa_de_aparitii();
protected:
string Titlu, Editura, Autor;
int An, Tiraj, Numar, Frecventa_de_aparitii;
};
class Carti: public Publicatii , public virtual Biblioteca
{
public:
void readBook();
Carti();
void insertMyBook();
void writeBookFile();
void inTitlu(Carti& a);
void inEditura(Carti& a);
void inAutor(Carti& a);
void inTiraj(Carti& a);
void inAn(Carti& a);
protected:
list<Carti*>books;
list<Carti*>::iterator i;
};
class Reviste: public Publicatii , public virtual Biblioteca
{
public:
void readMagazine();
Reviste();
void insertMyMagazine();
void writeMagazineFile();
protected:
list<Reviste*> magazine;
list<Reviste*>::iterator j;
};
The other cpp file of the header
#include<iostream>
#include<string>
#include"biblioteca.h"
#include <list>
#include<fstream>
//-----Biblioteca------
Biblioteca::Biblioteca()
{
Memorare.open("in.txt");
}
void Biblioteca::closeFile()
{
Memorare.close();
}
bool Biblioteca::chose()
{
int k;
cout << "Ce doriti sa introduceti?" << endl << endl;
cout << "1--Carte" << endl;
cout << "2--Biblioteca" << endl;
cin >> k;
switch (k)
{
case 1:
return true;
break;
case 2:
return false;
break;
}
}
//-------Publicatii------
string Publicatii::retTitlu()
{
return Titlu;
}
string Publicatii::retEditura()
{
return Editura;
}
string Publicatii::retAutor()
{
return Autor;
}
int Publicatii::retAn()
{
return An;
}
int Publicatii::retTiraj()
{
return Tiraj;
}
int Publicatii::retNumar()
{
return Numar;
}
int Publicatii::retFrecventa_de_aparitii()
{
return Frecventa_de_aparitii;
}
//---------Carti---------
void Carti::inTitlu(Carti& a)
{
Titlu = a.retTitlu();
}
void Carti::inEditura(Carti& a)
{
Editura = a.retEditura();
}
void Carti::inAutor(Carti& a)
{
Autor = a.retAutor();
}
void Carti::inTiraj(Carti& a)
{
Tiraj = a.retTiraj();
}
void Carti::inAn(Carti& a)
{
An = a.retAn();
}
void Carti::readBook()
{
cout << "\nO noua carte" << endl<<endl;
cout << "\nTitlu= ";
cin >> Titlu;
cout << "\nEditura= ";
cin >> Editura;
cout << "\nAn= ";
cin >> An;
cout << "\nTiraj= ";
cin >> Tiraj;
cout << "\nAutor= ";
cin >> Autor;
}
Carti::Carti()
{
books.resize(1);//one book
}
void Carti::insertMyBook()
{
Carti carti;
for (i = books.begin(); i != books.end(); i++)
{
carti.readBook();
(*i)->inTitlu(carti);
(*i)->inEditura(carti);
(*i)->inAn(carti);
(*i)->inTiraj(carti);
(*i)->inAutor(carti);
//books.insert(i, *i);
}
}
void Carti::writeBookFile()
{
Memorare << "---Carti---" << endl;
for (i = books.begin(); i != books.end(); i++)
Memorare << *i << " ";
}
//-------Reviste--------
void Reviste::readMagazine()
{
cout << "\nO noua revista" << endl<< endl;
cout << "\nTitlu= ";
cin >> Titlu;
cout << "\nEditura= ";
cin >> Editura;
cout << "\nAn= ";
cin >> An;
cout << "\nTiraj= ";
cin >> Tiraj;
cout << "\nNumar= ";
cin >> Numar;
cout << "\nFrecventa de aparitie= ";
cin >> Frecventa_de_aparitii;
}
Reviste::Reviste()
{
magazine.resize(1);//one magazine
}
void Reviste::insertMyMagazine()
{
Reviste reviste;
for (j = magazine.begin(); j != magazine.end(); j++)
{
reviste.readMagazine();
//some conde
magazine.insert(j, *j);
}
}
void Reviste::writeMagazineFile()
{
Memorare << "---Reviste---" << endl;
for (j = magazine.begin(); j != magazine.end(); j++)
cout << *j << " ";
}
Sorry for the code thone here, I'm new to Stackoverflow and I'm in a hurry, that's why I don't write "beautiful code". My problem is, when I want to just insert elements in my list
void Carti::insertMyBook()
{
Carti carti;
for (i = books.begin(); i != books.end(); i++)
{
carti.readBook();
(*i)->inTitlu(carti);
(*i)->inEditura(carti);
(*i)->inAn(carti);
(*i)->inTiraj(carti);
(*i)->inAutor(carti);
books.insert(i, *i);
}
}
it's working like a clockwork and after I compile I type some information from my keyboard and at the end I get a big error like "Acces Violation Reading 00000001C"
Why? I tried other metods like allocating dynamic memory with the new operator, I tried a lot of things but in the end I have like this error or type "example" doesn't match with "example".
Sorry for my bad English spelling, but in this program I just wanted to make a program that reads magazines and boooks and stored to a library named "biblioteca", and "carte" means books and " Reviste" means magazine... and I want it to be memorized in a list because I need to insert elements or delete what ever book or magazine I choose...and all the information I want to be saved in a file for instance "out.txt" or "in.txt"
The crash is because the iterator is NULL at line (*i)->inTitlu(carti);.
The issue is in method:
Carti::Carti()
{
books.resize(1);//one book
}
and books are:
list<Carti*>books;
What you are trying to is to resize the list of Carti's to 1 but as you have a list of pointers to Carti objects rather than Carti objects, resizing operation will not create a Carti object by calling it's constructor but a pointer.
Apart from that you have major issues with your design and coding, a Carti object storing a list of other pointers-to-Carti objects definitely is not a good idea. You may consider creating another 'holding' class to store a list of Carti's you have created.

Method of storing a date

I was wondering if there is a way to get a date without writing your own function. Something such as accessing the date set for the system. I tried
char dateStr[9];
_strdate(dateStr);
with the included time header, but I got compiler error ISO C++ forbids declaration of _strdate with no type. I thought _strdate was already declared and defined in the header so it wouldn't need a type definition. Could the problem be that I have those 2 lines inside of a struct? Are there any better way to store a date? Thanks.
#include "std_lib_facilities.h"
//Classes-----------------------------------------------------------------------
class Book{
public:
Book(){}; // default constructor
//operators
friend ostream& operator<<(ostream& out, const Book& val);
bool Book::operator==(const Book& check);
//member functions
string title();
string author();
string genre();
int copyright();
void ISBN();
bool checkout();
private:
string title_;
string author_;
string genre_;
int copyright_;
int ISBN1;
int ISBN2;
int ISBN3;
char ISBN4;
bool checkout_;
};
class Patron{
public:
Patron(){}; //default constructor
//member functions
string name();
int libnumber();
double setfee();
private:
string name_;
int libnumber_;
double libfees;
};
class Library{
public:
vector<Book> books;
vector<Patron> patrons;
struct Transaction{
Book book;
Patron patron;};
vector<Transaction> transactions;
};
// Error Function---------------------------------------------------------------
void _error(const string& s)
{
cout << endl;
cout << "Error: " << s << endl;
cout << endl;
}
// Book Member Functions--------------------------------------------------------
string Book::title()
{
cout << "Title: ";
getline(cin,title_);
cout << endl;
return title_;
}
string Book::author()
{
cout << "Author: ";
getline(cin,author_);
cout << endl;
return author_;
}
string Book::genre()
{
cout << "Genre(Fiction, Nonfiction, Periodical, Biography, Children): ";
cin >> genre_;
cout << endl;
if((genre_!="Fiction")&&(genre_!="Nonfiction")&&(genre_!="Periodical")&&
(genre_!="Biography")&&(genre_!="Children")) _error("Invalid genre.");
else return genre_;
}
int Book::copyright()
{
cout << "Copyright: ";
cin >> copyright_;
cout << endl;
return copyright_;
}
void Book::ISBN()
{
cout << "ISBN (4 entries. Use spaces): ";
cin >> ISBN1 >> ISBN2 >> ISBN3 >> ISBN4;
if((ISBN1<0) || (ISBN2<0) || (ISBN3<0) || (ISBN1>9) || (ISBN2>9) || (ISBN3)>9)
_error("Must be single digit.");
else if(!isdigit(ISBN4) && !isalpha(ISBN4))
_error("Must be single digit or letter.");
else{ cout << endl;
return;}
}
bool Book::checkout()
{
char check;
cout << "Checked out?(Y or N): ";
cin >> check;
switch(check){
case 'Y':
cout << endl;
return true;
break;
case 'N':
cout << endl;
return false;
break;
default:
_error("Must be Y or N.");}
}
// Patron Member Functions------------------------------------------------------
string Patron::name()
{
cout << "Name: ";
getline(cin,name_);
cout << endl;
return name_;
}
int Patron::libnumber()
{
cout << "Libnumber: ";
cin >> libnumber_;
cout << endl;
return libnumber_;
}
double Patron::setfee()
{
cout << "Fee due: ";
cin >> libfees;
cout << endl;
return libfees;
}
// Patron Helper Functions------------------------------------------------------
bool isfee()
{
char isfee_;
cout << "Does patron have fee due?(Y or N): ";
cin >> isfee_;
cout << endl;
if((isfee_!='Y') && (isfee_!='N')) _error("Must use Y or N.");
else return(isfee_=='Y');
}
// Operator Overloads-----------------------------------------------------------
ostream& operator<<(ostream& out, const Book& val){
out << "Title: " << val.title_ << endl;
out << "Author: " << val.author_ << endl;
out << "ISBN: " << val.ISBN1 << "-" << val.ISBN2 << "-" << val.ISBN3 << "-" << val.ISBN4 << endl;
out << endl;
return out;}
bool Book::operator==(const Book& check){
return((ISBN1 == check.ISBN1) && (ISBN2 == check.ISBN2) && (ISBN3 == check.ISBN3)
&& (ISBN4 == check.ISBN4));}
// Main Helpers-----------------------------------------------------------------
void runBook()
{
Library bookstore;
char notfinished;
bool bookfinished = false;
while(!bookfinished)
{
Book book;
book.title();
book.author();
book.genre();
book.copyright();
book.ISBN();
book.checkout();
bookstore.books.push_back(book);
cout << "Do you wish to store another book?(Y or N): ";
cin >> notfinished;
if(notfinished == 'Y'){
cin.ignore();
cout << endl;}
else if(notfinished == 'N'){
bookfinished = true;
cout << endl;}
else _error("Must be Y or N");
}
}
void runPatron()
{
Library patronstore;
bool patronfinished = false;
char notfinished;
while(!patronfinished)
{
Patron patron;
patron.name();
patron.libnumber();
if(isfee()){
patron.setfee();}
cin.ignore();
runBook(); // Call book function
patronstore.patrons.push_back(patron);
cout << "Is there another patron?(Y or N): ";
cin >> notfinished;
if(notfinished == 'Y'){
cin.ignore();
cout << endl;}
else if(notfinished == 'N') patronfinished = true;
else _error("Must be Y or N");
}
}
// Main-------------------------------------------------------------------------
int main()
{
runPatron();
keep_window_open();
}
If you go to class Library and into the Transaction struct, that is where I want to store the date.
Where to start? Difficult to tell without seeing the code, but here's some thoughts.
First, you should probably NOT store the date as a character array within your struct because that will make manipulation of it awkward. Better to store it in it's native form as a time_t, and convert it to/from strings as required.
Second, if you must store it as ascii, don't store it as char[]. You're just asking for buffer overruns etc. Use string or vector
However, I think the real answer to your question concerns constructors. If you want Transaction to hold a date, then define it like this
struct Transaction
{
char dateStr[9];
}
If you want transactions to be datestamped, then assign the date in the constructor
struct Transaction
{
char dateStr[9];
Transaction()
{
_strdate(dateStr); // or asctime or whatever
}
}
Now, whenever you create a Transaction, it will automatically be filled with the return value from _strdate, whatever that is. Here's how I'd do it with time_t.
#include <stdio.h>
#include <time.h>
struct Transaction
{
time_t theTime;
Transaction()
{
theTime = time(NULL);
}
}
There is no such standard C++ function as strdate. Whether putting those lines "inside a struct" causes a problem is impossible to say without seing the code. I suggest what you really want is the asctime() function, or one of its relatives.