I am currently learning about classes and am having a problem in my class implementation file.
In my class header/specification file Book.h , I have the public member function setPages.
#ifndef BOOK_H
#define BOOK_H
#include <string>
#include "Author.h"
#include "Publisher.h"
class Book
{
private:
std::string _title;
std::string _edition;
int _pages;
int _copyrightYear;
Author _author;
Publisher _publisher;
public:
Book (std::string title, Author author, Publisher publisher)
{_title = title; _author = author; _publisher = publisher;}
void setPages (int pages);
void setCopyYear (int copyrightYear);
void setEdition (std::string edition);
std::string getTitle () const;
std::string getEditon () const;
int getPages () const;
int getCopyYear () const;
Author getAuthor () const;
Publisher getPublisher () const;
};
#endif
In my Book.cpp implementation file I have
#include <string>
#include "Author.h"
#include "Publisher.h"
#include "Book.h"
void Book::setPages (int pages)
{
_pages = pages;
}
I keep getting the error that Book is not a classname or namespace but I don't see what I've done wrong. I included my Book header file and checked to make sure everything was spelled correctly in the class. I've done the same thing in my other classes and it is working so I don't see why this isn't.
Any help appreciated thanks.
Here is Publisher.h and Author.h
#ifndef PUBLISHER_H
#define PUBLISHER_H
class Publisher
{
private:
std::string _name;
std::string _address;
std::string _phoneNumber;
public:
Publisher (std::string& name)
{_name=name;}
void setAddress (std::string address);
void setNumber (std::string phoneNumber);
std::string getAddress () const;
std::string getNumber () const;
bool operator==(std::string name)
{
if (_name == name)
return true;
else
return false;
};
#endif
and Author.H
#ifndef AUTHOR_H
#define AUTHOR_H
class Author
{
private:
std::string _name;
int _numberOfBooks;
public:
Author(std::string& name)
{_name = name;}
void setNumOfBooks (int numberOfBooks);
int getNoOfBooks () const;
bool operator==(std::string _name)
{
if (this->_name == _name)
return true;
else
return false;
}
};
#endif
Until #ahenderson decides to turn his comments into an answer:
bool operator==(std::string name) in "Publisher.h" is missing a brace in your example. is that actually in your code or a copy and paste error?
bool operator==(std::string name)
{
if (_name == name)
return true;
else
return false;
Oops, no brace here!
Suggestion: Simplify your operator== method:
The expression _name == name will already return true or false. No need to put it into an if clause that returns true or false.
Try this:
bool operator==(const std::string& name)
{
return (_name == name);
}
In the above example, the expression is evaluated and the result is returned, directly.
Also, you may run into compiler issues if your variables begin with an underscore, '_'. Change your naming convention so this issue doesn't raise its ugly head. Two common practices are to append a suffix, name_, or prefixing with something like m_name.
Related
I have been looking in different threads with this error which is quite common but it feels like the IDE I am using messed with my workspace and I can't quite find the problem. I am setting up an extremely basic class called "Movie" that is specified below:
Movie.hpp :
#ifndef MOVIE_HPP
#define MOVIE_HPP
#include <iostream>
#include <string>
using std::string, std::cout,std::size_t;
class Movie
{
private:
std::string name;
std::string rating;
int watched_ctr;
public:
Movie(const string& name, const string& rating, int watched_ctr);
~Movie();
//getters
string get_name() const;
string get_rating() const;
int get_watched() const;
//setters
void set_name(string name);
void set_rating(string rating);
void set_watched(int watched_ctr);
};
#endif // MOVIE_HPP
Movie.cpp:
#include <iostream>
#include <string>
#include "Movie.hpp"
using std::string, std::cout,std::size_t,std::endl;
Movie::Movie(const string& name, const string& rating, int watched_ctr)
: name(name) , rating(rating) , watched_ctr(watched_ctr) {
}
Movie::~Movie()
{
cout << "Destructor for Movies class called /n";
}
//Getters
string Movie::get_name(){return name;}
string Movie::get_rating(){return rating;}
string Movie::get_watched(){return watched_ctr;}
//Setters
void Movie::set_name(std::string n){this -> name = n;}
void Movie::set_rating(std::string rating){this -> rating = rating;}
void Movie::set_watched(int ctr){this -> watched_ctr = ctr;}
The main.cpp I am trying only consists in creating one Movie object:
#include <iostream>
#include <string>
#include "Movie.hpp"
using std::string, std::cout,std::size_t,std::endl;
int main()
{
Movie StarTrek("Star Trek", "G", 20);
}
As you can see, I set all the attribute to private in order to exercise with the set/get methods but I keep stumbling upon the same error on each of them stating >"C:/Users/.../ProjectsAndTests/MoviesClass/Movie.cpp:18:8: error: no declaration matches 'std::__cxx11::string Movie::get_name()"
if you could give me a hint on what might cause this error I would greatly appreciate thank you!
I tried opening another workspace with classes implemented inside of them and the syntax I am using is very close from this test workspace I opened which compiled fine (no error regarding declaration match).
There are 2 problems with your code.
First while defining the member functions outside class you're not using the const. So to solve this problem we must use const when defining the member function outside the class.
Second, the member function Movie::get_watched() is declared with the return type of string but while defining that member function you're using the return type int. To solve this, change the return type while defining the member function to match the return type in the declaration.
//----------------------vvvvv--------->added const
string Movie::get_name()const
{
return name;
}
string Movie::get_rating()const
{
return rating;
}
vvv------------------------------>changed return type to int
int Movie::get_watched()const
{
return watched_ctr;
}
Working demo
I've got error "redefinition of class Book". Thats my code:
Book.cpp
#include "Book.h"
using namespace std;
class Book {
string author, title;
public:
Book()
{
cout<<"Book()"<<endl;
author = "-";
title = "-";
}
Book(const string& autor, const string& tytul)
{
cout<<"Book(const string& autor, const string& tytul)"<<endl;
author = autor;
title = tytul;
}
Book(string&& autor, string&& tytul)
{
cout<<"Book(Book&& autor, Book&& tytul)"<<endl;
author=autor;
title=tytul;
}
Book(const Book& other)
:author(other.author),title(other.title)
{
cout<<"Book(const Book& other)"<<endl;
}
string GetAuthor()
{
return author;
}
string GetTitle()
{
return title;
}
void SetAuthor(const string &autor)
{
cout<<"Setter ze stalymi l-ref"<<endl;
author=autor;
}
void SetTitle(const string &tytul)
{
cout<<"Setter ze stalymi l-ref"<<endl;
title=tytul;
}
void SetAuthor(string &&autor)
{
cout<<"Setter r-ref"<<endl;
author=autor;
}
void SetTitle(string &&tytul)
{
cout<<"Setter r-ref"<<endl;
title=tytul;
}
//OPERATORY
Book& operator=(const Book& right)
{
cout<<"Book& operator=(const Book& right)"<<endl;
Book tmp = right;
swap(author,tmp.author);
swap(title,tmp.title);
return *this;
}
Book& operator=(Book&& right)
{
cout<<"Book& operator=(Book&& right)"<<endl;
swap(author,right.author);
swap(title,right.title);
return *this;
}
};
Book.h
#include <string>
using namespace std;
class Book {
string author, title;
public:
Book();
Book(const string& autor, const string& tytul);
Book(string&& autor, string&& tytul);
Book(const Book& other);
string GetAuthor();
string GetTitle();
void SetAuthor(const string &autor);
void SetTitle(const string &tytul);
void SetAuthor(string &&autor);
void SetTitle(string &&tytul);
//OPERATORY
Book& operator=(const Book& right);
Book& operator=(Book&& right);
};
SOLUTIONS: after time, I can see few problems:
Never add using namespace std; in header files (namespace in header files)
cpp file should define methods from header file
declare class in header file and implement in cpp file
class template thats how class should looks like
when you want to define method from header file do this in proper way: ClassName::method_type method_name (){...}
The preprocessor which handles header files and the #include directive basically copy-pastes the header file into the place of the #include directive.
That means the compiler will see this in your source file:
class Book { ... };
class Book { ... };
You can't define a class multiple times like this.
Instead only define the class in the header file (and remember to add header include guards), and then the source file defines (implements) the functions only.
So beyond adding include guards, keep the header file as it is. Then change the source file to something similar to this:
#include "Book.h"
Book::Book()
{
cout<<"Book()"<<endl;
author = "-";
title = "-";
}
// ...
std::string Book::GetAuthor()
{
return author;
}
// ... And so on, doing the same with all other functions
I am making a school assignment, but I am getting a strange error. I have tried to google it, but nothing helped.
So I have a file called main.cpp. Within this file I have some includes and code.
This:
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;
#include "RentalAdministration.h"
#include "Limousine.h"
#include "Sedan.h"
void addTestDataToAdministration(RentalAdministration* administration)
{
string licencePlates[] = {"SD-001", "SD-002", "SD-003", "SD-004", "LM-001", "LM-002"};
for (int i = 0; i < 4; i++)
{
Car* sedan = new Sedan("BMW", "535d", 2012 + i, licencePlates[i], false);
administration->Add(sedan);
}
for (int i = 4; i < 6; i++)
{
Car* limousine = new Limousine("Rolls Roys", "Phantom Extended Wheelbase", 2015, licencePlates[i], true);
administration->Add(limousine);
}
}
int main( void )
{
RentalAdministration administration;
addTestDataToAdministration(&administration);
}
So the compiler tells me that the variable: "RentalAdministration administration" does not exist.
So if we have look in my rentaladministration header. We see this:
#ifndef RENTALADMINISTRATION_H
#define RENTALADMINISTRATION_H
#include <vector>
#include "car.h"
class RentalAdministration
{
private:
std::vector<Car*> Cars;
Car* FindCar(std::string licencePlate);
Car* FindCarWithException(std::string licencePlate);
public:
std::vector<Car*> GetCars() const {return Cars;}
bool Add(Car* car);
bool RentCar(std::string licencePlate);
double ReturnCar(std::string licencePlate, int kilometers);
void CleanCar(std::string licencePlate);
RentalAdministration();
~RentalAdministration();
};
#endif
This is the exact error:
src/main.cpp:18:34: error: variable or field ‘addTestDataToAdministration’ declared void
void addTestDataToAdministration(RentalAdministration* administration)
^
src/main.cpp:18:34: error: ‘RentalAdministration’ was not declared in this scope
src/main.cpp:18:56: error: ‘administration’ was not declared in this scope
void addTestDataToAdministration(RentalAdministration* administration)
Help will be appreciated!
Edit:
I am getting warnings in sublime for the Sedan and Limousine headers. Something that has to do with some static constants. I think it was called a GNU extension. Maybe it has something to do with it.
Even when I comment the call of that function out. I get the same error.
I am calling that function nowhere else.
Some people say that the cause might be in these headers:
#ifndef LIMOUSINE_H
#define LIMOUSINE_H
#include "Car.h"
//c
class Limousine : public Car
{
private:
bool needsCleaning;
bool hasMiniBar;
static const double priceperkm = 2.5;
public:
double Return(int kilometers);
void Clean();
bool GetHasMiniBar() const { return hasMiniBar;}
void SetHasMiniBar(bool value) {hasMiniBar = value;}
Limousine(std::string manufacturer, std::string model, int buildYear, std::string licencePlate, bool hasminiBar);
~Limousine();
};
#endif
2:
#ifndef SEDAN_H
#define SEDAN_H
#include "Car.h"
//c
class Sedan : public Car
{
private:
int lastCleanedAtKm;
bool hasTowBar;
bool needsCleaning;
static const double priceperKm = 0.29;
public:
void Clean();
int GetLastCleanedAtKm() const {return lastCleanedAtKm;}
void SetLastCleanedAtKm(bool value){ lastCleanedAtKm = value;}
bool GetHasTowBar() const {return hasTowBar;}
void SetHasTowBar(bool value) {hasTowBar = value;}
bool GetNeedsCleaning() const {return needsCleaning;}
void SetNeedsCleaning(bool value){needsCleaning = value;}
Sedan(std::string manufacturer, std::string model, int buildYear, std::string licencePlate, bool hastowBar);
~Sedan();
};
#endif
class Limousine : public Car
{
private:
static const double priceperkm = 2.5;
...
}
Remove the static and declare the member simply as const double, example:
class Limousine : public Car
{
private:
const double priceperkm = 2.5;
...
}
The error message ‘RentalAdministration’ was not declared in this scope indicates that the right header file for RentalAdministration was not included. Check the file names to make sure class declaration for RentalAdministration is in the right file.
Restarting the terminal has somehow solved this error. I got another error this time, which I solved already. I missed the destructor. It stood in the header file, but not in the cpp file.
Buggy terminals...
I am trying to use constructor initializer for name and time but the visual studio is giving me errors, I do not see any issues with it, it seems fine to me, I tried to see the problem, I tried other things as well, Please Help. Thanks you in advance.
Any help really appreciated, I added all the header file and implementation of Entry class, I know it seems, I added so you can see it.
// Entry.h
#pragma once
#include <iostream>
#include <string>
#include "RelationType.h"
using namespace std;
class Name
{
public:
Name();
Name(string firstName, string middleName, string lastName);
string GetFristName() const;
string GetLastName() const;
string GetMiddleName() const;
char GetMiddleInitial() const;
RelationType ComparedTo(Name otherName) const;
private:
string first;
string last;
string middle;
};
//Entry.cpp
#include "Entry.h"
#include<iostream>
#include <string>
using namespace std;
Entry::Entry() {}
Entry::Entry(string firstName, string middleName, string lastName,
int initHours, int initMinutes, int initSeconds)
: name{ (firstName, middleName, lastName) , //name is where its mad at
time(initHours, initMinutes, initSeconds) } {}
string Entry::GetNameStr () const
{
return (name.GetFirstName() + ' ' + name.GetLastName());
}
string Entry::GetTimeStr () const
{
return (name.FirstName() + ' ' + name.LastName());
}
// Name.h
#pragma once
#include <iostream>
#include <string>
#include "RelationType.h"
using namespace std;
class Name
{
public:
Name();
Name(string firstName, string middleName, string lastName);
string GetFristName() const;
string GetLastName() const;
string GetMiddleName() const;
char GetMiddleInitial() const;
RelationType ComparedTo(Name otherName) const;
private:
string first;
string last;
string middle;
};
// RealtionType.h
#pragma once
#ifndef RELATION
#define RELATION
enum RelationType { BEFORE, SAME, AFTER };
#endif
// TimeOfDay.h
#pragma once
class TimeOfDay
{
public:
//Intentionally missed const, see what happened without const
TimeOfDay(); // zero timepfday object
TimeOfDay(int hours, int minutes, int seconds); //takes 3 parameters
TimeOfDay Increment() const; //increment by 1 sec
void Write() const; //write the timeofday obj to print
bool Equal(TimeOfDay otherTime) const; //true if timeofday obj equals othertime
bool LessThan(TimeOfDay otherTime) const; //const, true if the timeofday obj is
//before itherTime
private:
int hours;
int minutes;
int seconds;
};
Your Entry class constructor code should be something like below
Entry::Entry(string firstName, string middleName, string lastName,
int initHours, int initMinutes, int initSeconds)
: name(firstName, middleName, lastName)
, time(initHours, initMinutes, initSeconds) {}
I just moved from C to C++, and now work with lists.
I have a class called "message", and I need to have a class called "line",
which should have a list of messages in its properties. as I learned, the object's properties should be initialized in the constructor's initialization list, and i had the "urge" to initialize the messages list in addition to the rest of the properties (some strings and doubles). is that "urge" justified? does the list need to be initialized?
here is my code.
the purpose is to create an empty list of lines, and the constructor I'm talking about is the one in line.cpp
//-------------------
//Code for line.h:
//-------------------
#ifndef LINE_H_
#define LINE_H_
#include "message.h"
#include <string>
#include <list>
using namespace std;
namespace test
{
using std::string;
class Line
{
public:
// constractor with parameters
Line(const string& phoneStr, double callRate, double messageRate);
//function to get phone string
string getPhoneStr() const;
double getCallRate() const;
double getMessageRate() const;
double getLastBill() const;
void addMessage(const string& phoneStr);
private:
string mPhoneStr;
list<Message> mMessages;
double mMessageRate;
double mLastBill;
};
}
#endif /* LINE_H_ */
//-------------------
//Code for line.cpp:
//-------------------
#include "line.h"
namespace test
{
Line::Line(const string& phoneStr, double callRate, double messageRate)
: mPhoneStr(phoneStr), mCallRate(callRate), mMessageRate(messageRate),
mLastBill(0) {}
//getters:
string Line::getPhoneStr() const
{
return mPhoneStr;
}
double Line::getCallRate() const
{
return mCallRate;
}
double Line::getMessageRate() const
{
return mMessageRate;
}
double Line::getLastBill() const
{
return mLastBill;
}
}
//-------------------
//Code for message.h:
//-------------------
#ifndef MESSAGE_H_
#define MESSAGE_H_
#include <string>
namespace test
{
using std::string;
class Message
{
public:
// constractor with parameters
Message(const string& phoneStr);
//function to get phone string
string getPhoneStr() const;
//function to set new phone string
void setPhoneStr(const string& phoneStr);
private:
string mPhoneStr;
};
}
#endif /* MESSAGE_H_ */
//-----------------------------------------------------------------------
//---------------------
//code for message.cpp:
//---------------------
#include "message.h"
namespace test
{
Message::Message(const string& phoneStr) : mPhoneStr(phoneStr) {}
string Message::getPhoneStr() const
{
return mPhoneStr;
}
void Message::setPhoneStr(const string& phoneStr)
{
mPhoneStr = phoneStr;
}
}
The initialization list is for initializing any base classes and member variables. The body of the constructor is meant to run any other code that you need before the object can be considered initialized.
I'm having a hard time understanding your situation, but hopefully the above helps.
You don't have to do everything in the initialisation list. It's hard to tell without seeing some code, but it sounds like adding the messages would be better done in the body of the constructor.