overiding functions defined in a base class with a child class - c++

I am new to C++ and trying to understand inheritance in this language. I have created a Ship class, defined some constructors, mutators, and a print function that should cout some info about the ship. I have two derived classes, one a Cruise class and another a Cargo Class. The first time I compiled a test of the Cruise class everything worked fine. After implementing the Cargo class I could no longer compile my code. Both classes are very similar and implemented nearly identically. Here is my code, the error I have recieved is underneath.
ship.cpp (defines the ship class)
#include <iostream>
#include <string>
using namespace std;
class Ship {
private:
string _strName, _strYear;
public:
//Constructors
Ship();
Ship(string, string);
//Mutators
void setName(string);
void setYear(string);
string getName();
string getYear();
//Methods
virtual void print();
};
//*************************************
// Cunstructors *
//*************************************
Ship::Ship() {
_strName = "NONE";
_strYear = "NONE";
}
Ship::Ship(string strname, string strYear) {
setName(strname);
setYear(strYear);
}
//*************************************
// MUTATORS *
//*************************************
void Ship::setName(string strName) {
_strName = strName;
}
void Ship::setYear(string strYear) {
_strYear = strYear;
}
string Ship::getName() {
return _strName;
}
string Ship::getYear() {
return _strYear;
}
//*************************************
// METHODS *
//*************************************
virtual void Ship::print() {
cout << _strName << endl
<< _strYear << endl;
}
CuiseShip.cpp (cruise ship class that inherits from Ship)
#include <iostream>
#include <string>
#include "ship.cpp"
using namespace std;
class CruiseShip:public Ship {
private:
int _intMaxPassengers;
public:
//Constructors
CruiseShip();
CruiseShip(string, string, int);
//Mutators
void setMaxPassengers(int);
int getMaxPassengers();
//Methods
void print();
};
//*************************************
// Cunstructors *
//*************************************
CruiseShip::CruiseShip() {
setName("NONE");
setYear("NONE");
setMaxPassengers(0);
}
CruiseShip::CruiseShip(string strname, string strYear, int intMaxPassengers) {
setName(strname);
setYear(strYear);
setMaxPassengers(intMaxPassengers);
}
//*************************************
// MUTATORS *
//*************************************
void CruiseShip::setMaxPassengers(int intMaxPassengers) {
_intMaxPassengers = intMaxPassengers;
}
int CruiseShip::getMaxPassengers() {
return _intMaxPassengers;
}
//*************************************
// METHODS *
//*************************************
void CruiseShip::print() {
string name = getName();
string year = getYear();
string maxPassengers = to_string(getMaxPassengers());
cout << name << endl
<< year << endl
<< maxPassengers << endl;;
}
CargoShip.cpp (inherits from ship)
#include <iostream>
#include <string>
#include "ship.cpp"
using namespace std;
class CargoShip: public Ship {
private:
int _intCapacity;
public:
//Constructors
CargoShip();
CargoShip(string, string, int);
//Mutators
void setCapacity(int);
int getCapacity();
//Methods
void print();
};
//*************************************
// Cunstructors *
//*************************************
CargoShip::CargoShip() {
setName("NONE");
setYear("NONE");
setCapacity(0);
}
CargoShip::CargoShip(string strname, string strYear, int intCapacity) {
setName(strname);
setYear(strYear);
setCapacity(intCapacity);
}
//*************************************
// MUTATORS *
//*************************************
void CargoShip::setCapacity(int intCapacity) {
_intCapacity = intCapacity;
}
int CargoShip::getCapacity() {
return _intCapacity;
}
//*************************************
// METHODS *
//*************************************
void CargoShip::print() {
string name = getName();
string year = getYear();
string capacity = to_string(getCapacity());
cout << name << endl
<< year << endl
<< capacity << endl;;
}
TEST.cpp (main() to impliment and test the code)
#include <iostream>
#include <string>
#include "CruiseShip.cpp"
#include "CargoShip.cpp"
int main() {
CruiseShip cruise("cruise", "1862", 25);
CargoShip cargo("Mellinium Falcon", "a long time ago", 100);
cruise.print();
cargo.print();
return 0;
}
Compile Error
In file included from CargoShip.cpp:3:0,
from Test.cpp:4:
ship.cpp:5:7: error: redefinition of ‘class Ship’
class Ship {
^
In file included from CruiseShip.cpp:3:0,
from Test.cpp:3:
ship.cpp:5:7: error: previous definition of ‘class Ship’
class Ship {
^
In file included from CargoShip.cpp:3:0,
from Test.cpp:4:
ship.cpp:27:1: error: redefinition of ‘Ship::Ship()’
Ship::Ship() {
^
In file included from CruiseShip.cpp:3:0,
from Test.cpp:3:
ship.cpp:27:1: note: ‘Ship::Ship()’ previously defined here
Ship::Ship() {
^
In file included from CargoShip.cpp:3:0,
from Test.cpp:4:
ship.cpp:31:1: error: redefinition of ‘Ship::Ship(std::__cxx11::string, std::__cxx11::string)’
Ship::Ship(string strname, string strYear) {
^
In file included from CruiseShip.cpp:3:0,
from Test.cpp:3:
ship.cpp:31:1: note: ‘Ship::Ship(std::__cxx11::string, std::__cxx11::string)’ previously defined here
Ship::Ship(string strname, string strYear) {
^
In file included from CargoShip.cpp:3:0,
from Test.cpp:4:
ship.cpp:39:6: error: redefinition of ‘void Ship::setName(std::__cxx11::string)’
void Ship::setName(string strName) {
^
In file included from CruiseShip.cpp:3:0,
from Test.cpp:3:
ship.cpp:39:6: note: ‘void Ship::setName(std::__cxx11::string)’ previously defined here
void Ship::setName(string strName) {
^
In file included from CargoShip.cpp:3:0,
from Test.cpp:4:
ship.cpp:43:6: error: redefinition of ‘void Ship::setYear(std::__cxx11::string)’
void Ship::setYear(string strYear) {
^
In file included from CruiseShip.cpp:3:0,
from Test.cpp:3:
ship.cpp:43:6: note: ‘void Ship::setYear(std::__cxx11::string)’ previously defined here
void Ship::setYear(string strYear) {
^
In file included from CargoShip.cpp:3:0,
from Test.cpp:4:
ship.cpp:47:8: error: redefinition of ‘std::__cxx11::string Ship::getName()’
string Ship::getName() {
^
In file included from CruiseShip.cpp:3:0,
from Test.cpp:3:
ship.cpp:47:8: note: ‘std::__cxx11::string Ship::getName()’ previously defined here
string Ship::getName() {
^
In file included from CargoShip.cpp:3:0,
from Test.cpp:4:
ship.cpp:51:8: error: redefinition of ‘std::__cxx11::string Ship::getYear()’
string Ship::getYear() {
^
In file included from CruiseShip.cpp:3:0,
from Test.cpp:3:
ship.cpp:51:8: note: ‘std::__cxx11::string Ship::getYear()’ previously defined here
string Ship::getYear() {
^
In file included from CargoShip.cpp:3:0,
from Test.cpp:4:
ship.cpp:58:6: error: redefinition of ‘void Ship::print()’
void Ship::print() {
^
In file included from CruiseShip.cpp:3:0,
from Test.cpp:3:
ship.cpp:58:6: note: ‘void Ship::print()’ previously defined here
void Ship::print() {
^
This error makes little since to me and I can't seem to find a solution. The compiler seems to be telling my that I am trying to redifine the Ship class. Can someone explain what is going on?

You shouldn't ever include .cpp files from you're main file. imagine that #including .cpp files are a copy and paste, and you're including the .cpp files in the main, and in the ship files - which results in multiple copies of these copies, and thus the compiler things you have defined it more than once.
You must place the class definition in the .h files - WITH HEADER GUARDS to protect from this duplication, then the implementation details in the .cpp file. Example:
ship.hpp
// Protects from multiple copies
#ifndef _SHIP_H_
#define _SHIP_H_
#include <iostream>
#include <string>
using namespace std;
class Ship {
private:
string _strName, _strYear;
public:
//Constructors
Ship();
Ship(string, string);
//Mutators
void setName(string);
void setYear(string);
string getName();
string getYear();
//Methods
virtual void print();
};
#endif // _SHIP_H_
ship.cpp
#include "ship.hpp" // this .cpp file INCLUDES the .hpp so it can match the functions
//*************************************
// Constructors *
//*************************************
Ship::Ship() {
_strName = "NONE";
_strYear = "NONE";
}
Ship::Ship(string strname, string strYear) {
setName(strname);
setYear(strYear);
}
//*************************************
// MUTATORS *
//*************************************
void Ship::setName(string strName) {
_strName = strName;
}
void Ship::setYear(string strYear) {
_strYear = strYear;
}
string Ship::getName() {
return _strName;
}
string Ship::getYear() {
return _strYear;
}
//*************************************
// METHODS *
//*************************************
virtual void Ship::print() {
cout << _strName << endl
<< _strYear << endl;
}
repeat the same for the other files.
main.cpp
#include <iostream>
#include <string>
#include "CruiseShip.hpp" // include .hpp files. Linker will link the .hpp functions with the .cpp implementations.
#include "CargoShip.hpp" // same here
int main() {
CruiseShip cruise("cruise", "1862", 25);
CargoShip cargo("Mellinium Falcon", "a long time ago", 100);
cruise.print();
cargo.print();
return 0;
}
To build, you must compile all of the .cpp files separately to ensure they do not have name clashes. They will be linked with the main.cpp automatically:
g++ --std=c++0x ship.cpp cargo.cpp main.cpp ... etc etc etc

Related

Error in redefinition of subclass in C++

i get from compiler the following error:
uni.cpp:63:1: error: redefinition of ‘Studente::Studente()’
Studente::Studente() : Persona(){
^
In file included from uni.cpp:1:0:
uni.h:34:5: note: ‘Studente::Studente()’ previously defined here
Studente():Persona(){};
^
uni.cpp:68:1: error: redefinition of ‘Studente::Studente(std::__cxx11::string, std::__cxx11::string, int, int, int, std::__cxx11::string, std::__cxx11::string)’
Studente::Studente(string nome_,string cognome_,int anno_,int mese_,int giorno_,string facolta_,string corso_) : Persona(nome_,cognome_,anno_,mese_,gi
^
In file included from uni.cpp:1:0:
uni.h:35:5: note: ‘Studente::Studente(std::__cxx11::string, std::__cxx11::string, int, int, int, std::__cxx11::string, std::__cxx11::string)’ previously defined here
Studente(string nome_,string cognome_,int anno_,int mese_,int giorno_,string facolta_,string corso_) : Persona(nome_,cognome_,anno_,mese_,giorno_)
^
And can't find out what's wrong
The file are:
UNI.H
#ifndef _UNI_H_
#define _UNI_H_
#include <string>
#include <iostream>
using namespace std;
class Persona{
private:
string nome;
string cognome;
int anno;
int mese;
int giorno;
public:
Persona();
Persona(string nome_,string cognome_,int anno_,int mese_,int giorno_);
void SetNome(string nome_);
void SetCognome(string cognome_);
void SetAnno(int anno_);
void SetMese(int mese_);
void SetGiorno(int giorno_);
string GetNome();
string GetCognome();
int GetAnno();
int GetMese();
int GetGiorno();
};
class Studente : public Persona{
private:
string facolta;
string corso;
public:
Studente():Persona(){};
Studente(string nome_,string cognome_,int anno_,int mese_,int giorno_,string facolta_,string corso_) : Persona(nome_,cognome_,anno_,mese_,giorno_){};
void SetFacolta(string facolta_);
void SetCorso(string corso_);
string GetFacolta();
string GetCorso();
};
#endif
UNI.CPP
#include "uni.h"
#include <iostream>
#include <string>
using namespace std;
Persona::Persona(){
SetNome("");
SetCognome("");
SetAnno(0);
SetMese(0);
SetGiorno(0);
}
Persona::Persona(string nome_,string cognome_,int anno_,int mese_,int giorno_){
SetNome(nome_);
SetCognome(cognome_);
SetAnno(anno_);
SetMese(mese_);
SetGiorno(giorno_);
}
void Persona::SetNome(string nome_){
nome=nome_;
}
void Persona::SetCognome(string cognome_){
cognome=cognome_;
}
void Persona::SetAnno(int anno_){
anno=anno_;
}
void Persona::SetMese(int mese_){
mese=mese_;
}
void Persona::SetGiorno(int giorno_){
giorno=giorno_;
}
string Persona::GetNome(){
return nome;
}
string Persona::GetCognome(){
return cognome;
}
int Persona::GetAnno(){
return anno;
}
int Persona::GetMese(){
return mese;
}
int Persona::GetGiorno(){
return giorno;
}
Studente::Studente() : Persona(){
SetFacolta("");
SetCorso("");
}
Studente::Studente(string nome_,string cognome_,int anno_,int mese_,int giorno_,string facolta_,string corso_) : Persona(nome_,cognome_,anno_,mese_,giorno_){
SetFacolta(facolta_);
SetCorso(corso_);
}
void Studente::SetFacolta(string facolta_){
facolta=facolta_;
}
void Studente::SetCorso(string corso_){
corso=corso_;
}
string Studente::GetFacolta(){
return facolta;
}
string Studente::GetCorso(){
return corso;
}
I know the main is missing... but that sure is not the problem!
It seems that the compiler tries to redefine the classes in the uni.cpp file.
Thanks!
Because, you're defining Studente's Constructor twice.
In the header:
Studente():Persona(){}; This should just be Studente();
Same with the other constructor.
The problem is this constructor definition in the header:
Studente():Persona(){};
replace it with a declaration, since you have a definition in the .cpp:
Studente();
In uni.h in the class Studente you have
Studente():Persona(){};
This declares and defines a default constructor for Studente. Then in uni.cpp you have
Studente::Studente() : Persona(){
SetFacolta("");
SetCorso("");
}
Which redefines the default constructor. You need to remove one of the definitions or change
Studente():Persona(){};
to
Studente();

C++ Template Class with Template Constructor

I tried to implement Properties in c++. I don't no why but if I want to compile my code there are quite a lot of errors. The main Idea was, that a template class and the tamplate constructor will give the requirement Informations.
I would be grateful if somebody could help me!
Compiling Message:
pi#raspberrypi ~/dev/property $ gcc -std=c++0x -o PropertyTest2 PropertyTest2.cpp
PropertyTest2.cpp:22:16: error: expected ‘;’ at end of member declaration
PropertyTest2.cpp:22:19: error: expected unqualified-id before ‘<’ token
PropertyTest2.cpp: In function ‘int main()’:
PropertyTest2.cpp:34:20: error: use of deleted function ‘PropertyTestClass::PropertyTestClass()’
PropertyTest2.cpp:8:7: error: ‘PropertyTestClass::PropertyTestClass()’ is implicitly deleted because the default definition would be ill-formed:
PropertyTest2.cpp:8:7: error: no matching function for call to ‘Property<int>::Property()’
PropertyTest2.cpp:8:7: note: candidates are:
Property4.cpp:21:2: note: template<int (** G)(), void (** S)(int&)> Property::Property()
Property4.cpp:6:7: note: constexpr Property<int>::Property(const Property<int>&)
Property4.cpp:6:7: note: candidate expects 1 argument, 0 provided
Property4.cpp:6:7: note: constexpr Property<int>::Property(Property<int>&&)
Property4.cpp:6:7: note: candidate expects 1 argument, 0 provided
PropertyTest2.cpp:38:20: error: no matching function for call to ‘Property<int>::Set(int)’
PropertyTest2.cpp:38:20: note: candidate is:
Property4.cpp:30:7: note: void Property<T>::Set(T&) [with T = int]
Property4.cpp:30:7: note: no known conversion for argument 1 from ‘int’ to ‘int&’
Property Class (Property.cpp)
#ifndef __PROPERTY_FH__
#define __PROPERTY_FH__
template <class T>
class Property {
private:
typedef T (*TGetter)(void);
typedef void (*TSetter)(T &);
TGetter Getter;
TSetter Setter;
public:
typedef T type;
template<TGetter *G,
TSetter *S
>
Property() {
this->Getter = G;
this->Setter = S;
}
T Get(void) {
return (this->Getter)();
}
void Set(T &value) {
(this->Setter)(value);
}
};
#endif
Testing file (PropertyTest.cpp):
#ifndef __PROPERTY_TEST_FH__
#define __PROPERTY_TEST_FH__
#include <iostream>
#include "Property.cpp"
class PropertyTestClass {
private:
// ReadWrite Property for age
int _age;
int AgeGetter(void) {
return this->_age;
}
void AgeSetter(int &value) {
this->_age = value;
}
public:
// ReadWrite Property for age
Property<int> age<&PropertyTestClass::AgeGetter, &PropertyTestClass::AgeSetter>;
};
#endif
/**
* Program Entry
**/
int main() {
std::cout << "Property Test Programm\n\n";
PropertyTestClass propTest;
std::cout << "ReadWrite Property for age\n";
propTest.age.Set(5);
std::cout << propTest.age.Get() << "\n";
return 0;
}
Ok, this time fixed all the problems in your code.
Property.cpp:
#ifndef __PROPERTY_FH__
#define __PROPERTY_FH__
#include <boost/function.hpp>
template <class T>
class Property {
private:
typedef boost::function <T()> TGetter;
typedef boost::function <void(const T&)> TSetter;
TGetter Getter;
TSetter Setter;
public:
typedef T type;
Property(TGetter G, TSetter S) {
this->Getter = G;
this->Setter = S;
}
T Get(void) {
return (this->Getter)();
}
void Set(const T &value) {
(this->Setter)(value);
}
};
#endif
PropertyTests.cpp:
#ifndef __PROPERTY_TEST_FH__
#define __PROPERTY_TEST_FH__
#include <iostream>
#include <boost/bind.hpp>
#include "Property.cpp"
class PropertyTestClass {
private:
// ReadWrite Property for age
int _age;
int AgeGetter() {
return this->_age;
}
void AgeSetter(const int &value) {
this->_age = value;
}
public:
// ReadWrite Property for age
Property<int> age;
PropertyTestClass() : age(
boost::bind(&PropertyTestClass::AgeGetter, this),
boost::bind(&PropertyTestClass::AgeSetter, this, _1))
{}
};
#endif
/**
* Program Entry
**/
int main() {
std::cout << "Property Test Programm\n\n";
PropertyTestClass propTest;
std::cout << "ReadWrite Property for age\n";
propTest.age.Set(5);
std::cout << propTest.age.Get() << "\n";
return 0;
}
Output:
$ ./a.out
Property Test Programm
ReadWrite Property for age
5

error on include the fstream.h header

I am reading a book "Data Structures and Algorithms in C++" which was published at 2001, I think the c++ compiler should be changed a lot since that time, because I found the code in the book can not be compiled.
#include <fstream.h>
#include <string.h>
So I Google for the answer, and changed the code to
#include <fstream>
#include <cstring>
using namespace std;
But when I tried to compile the code, well, I got some error I have not ever seen:
oo#oo:~/raf$ g++ database.cpp personal.cpp student.cpp useDatabase.cpp -o useDatabase
In file included from /usr/include/c++/4.6/ios:45:0,
from /usr/include/c++/4.6/istream:40,
from /usr/include/c++/4.6/fstream:40,
from personal.h:4,
from student.h:1,
from student.cpp:1:
/usr/include/c++/4.6/bits/ios_base.h: In copy constructor ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’:
/usr/include/c++/4.6/bits/ios_base.h:788:5: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/include/c++/4.6/bits/basic_ios.h:64:11: error: within this context
In file included from /usr/include/c++/4.6/istream:41:0,
from /usr/include/c++/4.6/fstream:40,
from personal.h:4,
from student.h:1,
from student.cpp:1:
/usr/include/c++/4.6/ostream: In copy constructor ‘std::basic_ostream<char>::basic_ostream(const std::basic_ostream<char>&)’:
/usr/include/c++/4.6/ostream:57:11: note: synthesized method ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’ first required here
In file included from student.cpp:1:0:
student.h: In function ‘std::ostream& operator<<(std::ostream&, Student&)’:
student.h:17:39: note: synthesized method ‘std::basic_ostream<char>::basic_ostream(const std::basic_ostream<char>&)’ first required here
student.h:15:18: error: initializing argument 1 of ‘std::ostream& Student::writeLegibly(std::ostream)’
student.cpp: At global scope:
student.cpp:24:10: error: prototype for ‘std::ostream& Student::writeLegibly(std::ostream&)’ does not match any in class ‘Student’
student.h:15:18: error: candidate is: std::ostream& Student::writeLegibly(std::ostream)
student.cpp: In member function ‘std::istream& Student::readFromConsole(std::istream&)’:
student.cpp:34:5: error: ‘cout’ was not declared in this scope
In file included from /usr/include/c++/4.6/ios:45:0,
from /usr/include/c++/4.6/ostream:40,
from /usr/include/c++/4.6/iostream:40,
from useDatabase.cpp:1:
/usr/include/c++/4.6/bits/ios_base.h: In copy constructor ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’:
/usr/include/c++/4.6/bits/ios_base.h:788:5: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/include/c++/4.6/bits/basic_ios.h:64:11: error: within this context
In file included from /usr/include/c++/4.6/iostream:40:0,
from useDatabase.cpp:1:
/usr/include/c++/4.6/ostream: In copy constructor ‘std::basic_ostream<char>::basic_ostream(const std::basic_ostream<char>&)’:
/usr/include/c++/4.6/ostream:57:11: note: synthesized method ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’ first required here
In file included from useDatabase.cpp:2:0:
student.h: In function ‘std::ostream& operator<<(std::ostream&, Student&)’:
student.h:17:39: note: synthesized method ‘std::basic_ostream<char>::basic_ostream(const std::basic_ostream<char>&)’ first required here
student.h:15:18: error: initializing argument 1 of ‘std::ostream& Student::writeLegibly(std::ostream)’
oo#oo:~/raf$
I spent a lot of time to Google for the answer, but got even more error. Maybe I should register a Github account and upload my code there.
database.cpp
#include "database.h"
template<class T> Database<T>::Database() {
cout << "File name: ";
cin >> fName;
}
template<class T> void Database<T>::add(T& d){
database.open(fName, ios::in|ios::out|ios::binary);
database.seekp(0, ios::end);
d.writeToFile(database);
database.close();
}
template<class T> void Database<T>::modify(const T& d){
T tmp;
database.open(fName, ios::in|ios::out|ios::binary);
while(!database.eof()){
tmp.readFromFile(database);
if (tmp == d){
cin >> tmp;
database.seekp(-d.size(), ios::cur);
tmp.writeToFile(database);
database.close();
return;
}
}
database.close();
cout << "The record to be modified is not in the database\n";
}
template<class T> bool Database<T>::find(const T& d){
T tmp;
database.open(fName, ios::in|ios::binary);
while(!database.eof()){
tmp.readFromFile(database);
if (tmp == d){
database.close();
return true;
}
}
database.close();
return false;
}
template<class T> ostream& Database<T>::print(ostream& out){
T tmp;
database.open(fName, ios::in|ios::binary);
while(1){
tmp.readFromFile(database);
if (database.eof())
break;
out << tmp << endl;
}
database.close();
return out;
}
template<class T> void Database<T>::run() {
char option[5];
T rec;
cout << "1.Add 2.Find 3.Modify a record 4.Exit\n";
cout << "Enter an option: ";
cin.getline(option, 4);
while (cin.getline(option, 4)){
if (*option == '1'){
cin >> rec;
add(rec);
}
else if (*option == '2'){
rec.readKey();
cout << "The record is ";
if (find(rec) == false)
cout << "not ";
cout << "in the database\n";
}
else if (*option == '3'){
rec.readKey();
modify(rec);
}
else if (*option != '4'){
cout << "Wrong option\n";
}
else return;
cout << *this;
cout << "Enter an option";
}
}
database.h
#ifndef DATABASE
#define DATABASE
#include <fstream>
#include <iostream>
using namespace std;
template<class T> class Database{
public:
Database();
void run();
private:
fstream database;
char fName[20];
ostream& print(ostream&);
void add(T&);
bool find(const T&);
void modify(const T&);
friend ostream& operator<<(ostream& out, Database& db) {
return db.print(out);
}
};
#endif
personal.cpp
#include "personal.h"
#include <iostream>
Personal::Personal() : nameLen(10), cityLen(10) {
name = new char[nameLen + 1];
city = new char[cityLen + 1];
}
Personal::Personal(char *ssn, char *n, char *c, int y, long s) : nameLen(10), cityLen(10) {
name = new char[nameLen + 1];
city = new char[cityLen + 1];
strcpy(SSN, ssn);
strcpy(name, n);
strcpy(city, c);
year = y;
salary = s;
}
void Personal::writeToFile(fstream& out) const {
out.write(SSN, 9);
out.write(name, nameLen);
out.write(city, cityLen);
out.write(reinterpret_cast<const char*>(&year), sizeof(int));
out.write(reinterpret_cast<const char*>(&salary), sizeof(int));
}
void Personal::readFromFile(fstream& in) {
in.read(SSN, 9);
in.read(name, nameLen);
in.read(city, cityLen);
in.read(reinterpret_cast<char *>(&year), sizeof(int));
in.read(reinterpret_cast<char *>(&salary), sizeof(int));
}
void Personal::readKey() {
char s[80];
cout << "Enter SSN: ";
cin.getline(s, 80);
strncpy(SSN, s, 9);
}
ostream& Personal::writeLegibly(ostream& out){
SSN[9] = name[nameLen] = city[cityLen] = '\0';
out << "SSN = " << SSN << ", name = " << name
<< ", city = " << city << ", year = " << year
<< ", salary = " << salary;
return out;
}
istream& Personal::readFromConsole(istream& in){
char s[80];
cout << "SSN: ";
in.getline(s, 80);
strncpy(SSN, s, 9);
cout << "Name: ";
in.getline(s, 80);
strncpy(name, s, nameLen);
cout << "City: ";
in.getline(s, 80);
strncpy(city, s, cityLen);
cout << "Birthyear: ";
in >> year;
cout << "Salary: ";
in >> salary;
in.getline(s, 80); //get '\n'
return in;
}
personal.h
#ifndef PERSONAL
#define PERSONAL
#include <fstream>
#include <cstring>
using namespace std;
class Personal {
public:
Personal();
Personal(char*, char*, char*, int, long);
void writeToFile(fstream&) const;
void readFromFile(fstream&);
void readKey();
int size() const {
return 9 + nameLen + cityLen + sizeof(year) + sizeof(salary);
}
bool operator==(const Personal& pr) const{
return strcmp(pr.SSN, SSN) == 0;
}
protected:
const int nameLen, cityLen;
char SSN[10], *name, *city;
int year;
long salary;
ostream& writeLegibly(ostream&);
friend ostream& operator<<(ostream& out, Personal& pr){
return pr.writeLegibly(out);
}
istream& readFromConsole(istream&);
friend istream& operator>>(istream& in, Personal& pr){
return pr.readFromConsole(in);
}
};
#endif
student.cpp
#include "student.h"
Student::Student() : majorLen(10) {
Personal();
major = new char[majorLen + 1];
}
Student::Student(char *ssn, char *n, char *c, int y, long s, char *m): majorLen(11){
Personal(ssn, n, c, y, s);
major = new char[majorLen + 1];
strcpy(major, m);
}
void Student::writeToFile(fstream& out) const {
Personal::writeToFile(out);
out.write(major, majorLen);
}
void Student::readFromFile(fstream& in) {
Personal::readFromFile(in);
in.read(major, majorLen);
}
ostream& Student::writeLegibly(ostream &out){
Personal::writeLegibly(out);
major[majorLen] = '\0';
out << ", major = " << major;
return out;
}
istream& Student::readFromConsole(istream& in){
Personal::readFromConsole(in);
char s[80];
cout << "Major: ";
in.getline(s, 80);
strncpy(major, s, 9);
return in;
}
student.h
#include "personal.h"
class Student : public Personal {
public:
Student();
Student(char*, char*, char*, int, long, char*);
void writeToFile(fstream&) const;
void readFromFile(fstream&);
int size() const{
return Personal::size() + majorLen;
}
protected:
char *major;
const int majorLen;
ostream& writeLegibly(ostream);
friend ostream& operator<<(ostream& out, Student& sr){
return sr.writeLegibly(out);
}
istream& readFromConsole(istream&);
friend istream& operator>>(istream& in, Student& sr){
return sr.readFromConsole(in);
}
};
useDatabase.cpp
#include <iostream>
#include "student.h"
#include "personal.h"
#include "database.h"
int main(){
Database<Personal> db;
db.run();
}
This was a big — arguably too big — set of files to be analyzed in an SO question. You need to learn some methods of reducing the size of your problem for presentation to SO (or to Tech Support).
One of the first steps in C or C++ is to ensure that the headers you create compile cleanly. If the headers aren't clean, you won't be able to compile the code that uses the headers, so headers must be sorted out first.
To help me, I have a script that I call chkhdr:
#!/bin/sh
# Check whether headers compile
tmp=chkhdr-$$
trap 'rm -f $tmp.?; exit 1' 0 1 2 3 13 15
cat > $tmp.c <<EOF
#include HEADER /* Check self-containment */
#include HEADER /* Check idempotence */
int main(void) { return 0; }
EOF
options=
for file in "$#"
do
case "$file" in
(-*) options="$options $file";;
(*) echo "$file"
${CC:-gcc} $options -DHEADER="\"$file\"" -c $tmp.c
;;
esac
done
rm -f $tmp.?
trap 0
I use it to check that headers are both self-contained and idempotent. A self-contained header can be included without any other headers before it, and it compiles. That means it can be used anywhere its services are needed without further ado. An idempotent header can be included multiple times without causing trouble. (I mainly work in C, hence the default compiler is GCC rather than G++. But I can set CC=g++ in the environment to switch to C++ work.)
Your student.h header was not idempotent; I immediately added the standard stanzas at top and bottom:
#ifndef STUDENT_H_INCLUDED
#define STUDENT_H_INCLUDED
...original contents of student.h...
#endif /* STUDENT_H_INCLUDED */
The detailed choice of guard macro name is up to you; that's the naming scheme I use these days, but there's some merit in using something like an MD5 checksum of an draft of the header to give you a quasi-random guard macro.
The output from compiling the student.h header alone was:
In file included from chkhdr-8120.c:1:
/usr/include/c++/4.2.1/bits/ios_base.h: In copy constructor ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’:
/usr/include/c++/4.2.1/bits/ios_base.h:779: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/include/c++/4.2.1/iosfwd:55: error: within this context
/usr/include/c++/4.2.1/iosfwd: In copy constructor ‘std::basic_ostream<char, std::char_traits<char> >::basic_ostream(const std::basic_ostream<char, std::char_traits<char> >&)’:
/usr/include/c++/4.2.1/iosfwd:64: note: synthesized method ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’ first required here
student.h: In function ‘std::ostream& operator<<(std::ostream&, Student&)’:
student.h:20: note: synthesized method ‘std::basic_ostream<char, std::char_traits<char> >::basic_ostream(const std::basic_ostream<char, std::char_traits<char> >&)’ first required here
student.h:20: error: initializing argument 1 of ‘std::ostream& Student::writeLegibly(std::ostream)’
The last line of the error message points firmly at the issue; the other messages are somewhat tangential, and lead up to the crux message. (Very often, especially in C, the first error is the most significant. It was surprising to me that the last line was the key one.) Changing line 20 of student.h to read:
ostream& writeLegibly(ostream&);
resolved that problem, and the student.h header compiled cleanly. The other headers were also clean. Then it was a simple matter to compile the source files. Only student.cpp had an issue:
student.cpp: In member function ‘std::istream& Student::readFromConsole(std::istream&)’:
student.cpp:34: error: ‘cout’ was not declared in this scope
It sounds like a case of 'should use std::cout instead', but adding that leads to:
student.cpp: In member function ‘std::istream& Student::readFromConsole(std::istream&)’:
student.cpp:34: error: ‘cout’ is not a member of ‘std’
That is fixed by including #include <iostream>. Then the code compiles cleanly under:
g++ -c *.cpp
I can't link; I run into undefined references to the Database code, but that's not surprising.
Summary
The details of the fixes are not incredibly important. What is important is the techniques. The key techniques here are:
Ensure headers work cleanly on their own (chkhdr).
Tackle one file at a time.
Problem minimization.
We should not have had to deal with all the code; you should have been able to isolate the problems much better. This is an important skill in any situation where you're reporting software problems to others. Eliminate the extraneous, and reduce to bare essentials.
the errors report
student.cpp:34:5: error: ‘cout’ was not declared in this scope
I think you need
#include <iostream>
In Student change
ostream& writeLegibly(ostream);
to
ostream& writeLegibly(ostream&);
and that should fix a lot. By missing the ampersand you were trying to copy the stream.
While the compiler have changed C++ and C are backwards compatible. One of the strengths of the language. Anyway I have copied out your code into a VS2010 because it was easier for me to analyse the issues with it.
put the #include < iostream > in your personal.h. It is used by personal.cpp where you have a cout.
The signature in student.h of
ostream& writeLegibly(ostream);
is wrong, it should be:
ostream& writeLegibly(ostream&);
I have moved the implementation code in database.cpp into the database.h. Plain simple cut and paste above the #endif. Due to the template nature the compiler did not like it that it was in a separate implementation cpp.
Hope that helps.

class issue in C++

I have this in furniture.h:
#include <iostream>
#include <string>
using namespace std;
class Furniture {
public:
Furniture();
virtual ~Furniture();
void setname(string name);
void setprice(double price);
int getprice();
string getname();
private:
string name;
int price;
protected:
static int NumberOfItems;
int Id;
}
and this in furniture.cpp
#include "furniture.h"
void Furniture::setname(string name) {
this->name = name;
}
string Furniture::getname()
{
return this->name;
}
void Furniture::setprice(double price) {
this->price = price;
}
int Furniture::getprice() {
return this->price;
}
int main() {
Furniture *model = new Furniture();
model->setname("FinalDestiny");
model->setprice(149.99);
cout<<"Model name: "<<model->getname()<<" - price = "<<model->getprice();
}
But I get some errors like:
Error 1 error C2628: 'Furniture' followed by 'void' is illegal (did you forget a ';'?) c:\final\facultate\poo\laborator 1\furniture.cpp 3 1 POO_lab
Error 2 error C2556: 'Furniture Furniture::setname(std::string)' : overloaded function differs only by return type from 'void Furniture::setname(std::string)' c:\final\facultate\poo\laborator 1\furniture.cpp 3 1 POO_lab
Error 3 error C2371: 'Furniture::setname' : redefinition; different basic types c:\final\facultate\poo\laborator 1\furniture.cpp 3 1 POO_lab
Error 5 error C2264: 'Furniture::setname' : error in function definition or declaration; function not called c:\final\facultate\poo\laborator 1\furniture.cpp 19 1 POO_lab
What am I doing wrong?
You are missing a ; at the end of the class definition in your header file.
// ...snipped...
protected:
static int NumberOfItems;
int Id;
}; // <-- here
You've forgotten a semicolon at the end of your class definition.
// ...
protected:
static int NumberOfItems;
int Id;
}; // <--
I hate that about C++ :)
Two things;
You're not ending your class definition with a ;, you need one at the end of furniture.h.
You've declared that there's a constructor and destructor, but neither is implemented in your .cpp file.

unable to overload virtual function

I have a Network class, which I want two virtual functions which I am going to overload: airtime() and airtime(std::vector<int> freq_bins);
I define the class, and the functions at the bottom:
class Network
{
public:
// Properties of the network protocol
std::string _name;
std::vector<float> _channels;
float _bandwidth;
float _txtime;
// Properties of the specific network
int _id;
macs::mac_t _mac;
protocols::protocol_t _protocol;
bool _static;
float _desired_airtime;
float _act_airtime;
bool _active;
// Constructor
Network();
virtual float airtime() { };
virtual float airtime(std::vector<int> freq_bins) { };
};
Now, I have a second class which I want to overload them. Here is the header of this class:
#ifndef _CSMA_H_
#define _CSMA_H_
#include <string>
#include <vector>
#include <map>
#include "MACs.h"
#include "Protocols.h"
#include "Network.h"
class CSMA : public Network
{
public:
float center_freq;
CSMA();
float airtime();
float airtime(std::vector<int> freq_bins);
};
#endif
I then define them in CSMA.cpp:
#include <iostream>
#include <string>
#include <vector>
#include "MACs.h"
#include "Protocols.h"
#include "Network.h"
#include "Simulator.h"
#include "CSMA.h"
extern Simulator sim;
CSMA::CSMA() {
_mac = macs::CSMA;
}
float CSMA::airtime() {
return _act_airtime;
}
float CSMA::airtime(std::vector<int> freq_bins) {
return 1;
}
I get the warning on returning values, that's not a problem. But the errors I get when trying to compile this, I don't understand:
g++ -o hce_sim hce_sim.cpp Network.cpp CSMA.cpp -Wall
In file included from hce_sim.cpp:2:
Network.h:54: error: ‘virtual float Network::airtime(std::vector<int, std::allocator<int> >)’ cannot be overloaded
Network.h:49: error: with ‘virtual float Network::airtime(std::vector<int, std::allocator<int> >)’
Network.h: In member function ‘virtual float Network::airtime()’:
Network.h:53: warning: no return statement in function returning non-void
Network.h: In member function ‘virtual float Network::airtime(std::vector<int, std::allocator<int> >)’:
Network.h:54: warning: no return statement in function returning non-void
In file included from Network.cpp:6:
Network.h:54: error: ‘virtual float Network::airtime(std::vector<int, std::allocator<int> >)’ cannot be overloaded
Network.h:49: error: with ‘virtual float Network::airtime(std::vector<int, std::allocator<int> >)’
Network.h: In member function ‘virtual float Network::airtime()’:
Network.h:53: warning: no return statement in function returning non-void
Network.h: In member function ‘virtual float Network::airtime(std::vector<int, std::allocator<int> >)’:
Network.h:54: warning: no return statement in function returning non-void
In file included from CSMA.cpp:6:
Network.h:54: error: ‘virtual float Network::airtime(std::vector<int, std::allocator<int> >)’ cannot be overloaded
Network.h:49: error: with ‘virtual float Network::airtime(std::vector<int, std::allocator<int> >)’
I created a more simplified program to try and understand why I get this error, yet this simplified program works:
#include <iostream>
#include <vector>
class Base {
public:
Base() { }
virtual void check() { }
virtual void check(bool it) { }
};
class First : public Base {
public:
First() { }
void check() {
std::cout << "You are in check(void) !\n";
}
void check(bool it) {
std::cout << "You are in check(bool) !\n";
}
};
int main() {
First f;
f.check();
f.check(true);
}
Does anyone have any insight here?
Try pure virtual function declarations.
virtual float airtime() = 0;
virtual float airtime(std::vector<int> freq_bins) = 0;
The reason it fails is that you definitions are incorrect, they don't return anything even though you have specified that it should return float.
Tip: You really shouldn't expose the internal state of your class like that. Do some googling on encapsulation.