*EDITED*Thanks for the previous helps.Got this problem now, doesnt like the pr.AddEnumerator(&t); line of the code.But its the same like in the sample task.
The AddEnumerator() is a method in procedure.hpp :
void AddEnumerator(Enumerator<Item>* en){ enor = en;}.
Procedure is the base class.
Also in seqinfileenumerator.hpp:
class SeqInFileEnumerator : public Enumerator<Item>
and in linsearch.hpp:
class LinSearch : public Procedure<Item>
#include <iostream>
#include "linsearch.hpp"
#include "seqinfileenumerator.hpp"
using namespace std;
struct MyPair
{
int azon;
int osszeg;
friend ifstream& operator>>(ifstream& f, MyPair& df);
};
ifstream& operator>>(ifstream& f, MyPair& df)
{
f >> df.azon >> df.osszeg;
return f;
}
class MyLinSearch: public LinSearch <int, true>
{
bool Cond(const int& e) const
{
return e<=-100000;
}
};
class MySeqInFileEnumerator: public SeqInFileEnumerator <MyPair>
{
public:
MySeqInFileEnumerator(char const * p) : SeqInFileEnumerator<MyPair>(p) { }
void Next()
{
MyPair dx;
f >> dx;
df.azon=dx.azon;
df.osszeg=dx.osszeg;
while(dx.azon==df.azon)
{
dx.osszeg+=df.osszeg;
f >> dx;
}
}
};
int main()
{
MyLinSearch pr;
MySeqInFileEnumerator file_enum("input.txt");
pr.AddEnumerator(&file_enum);
pr.Run();
if (pr.Found())
{
cout << "false " << endl;
}
else cout << "true" << endl;
return 0;
}
Related
Vehicle header file
#define vehicle_h
#include "date.h"
#include "storable.cpp"
#include <string>
using namespace std;
typedef enum{bike = 1,car = 2,towera = 3} VehicleType;
class Vehicle : public Storable
{
private:
string registrationnumber;
VehicleType type;
int seats;
string companyname;
double pricePerKm;
Date PUCExpirationDate;
public:
Vehicle(
string registrationnumber,
VehicleType type,
int seats,
string companyname,
double pricePerKm,
Date PUCExpirationDate, long recordID);
string getregistrationnumber() const;
VehicleType getVehicleType() const;
string getVehicleTypeName() const;
int getseats() const;
string getcompanyName() const;
double getPricePerKm() const;
Date getPUCExpirationDate() const;
void setPricePerKm(double newPrice);
void display() const;
string toString() const;
void setDataForm (Storable * s);
};
#endif // vehicle
Vehicle
#include "Vehicle.h"
#include "STRING_HELPER.h"
const char DELIMETER =';';
Vehicle :: Vehicle(string registrationnumber,VehicleType type,int seats,
string companyName , double pricePerKm , Date PUCExpirationDate , long recordID=0):Storable(recordID)
{
this->registrationnumber =registrationnumber;
this->type= type;
this->seats = seats;
this-> companyname = companyname;
this->pricePerKm = pricePerKm;
this->PUCExpirationDate = PUCExpirationDate;
}
string Vehicle ::getregistrationnumber() const
{
return this->registrationnumber;
}
VehicleType Vehicle::getVehicleType() const
{
return this->type;
}
int Vehicle::getseats() const
{
return this->seats;
}
string Vehicle::getcompanyName() const
{
return this->companyname;
}
double Vehicle::getPricePerKm() const
{
return this->pricePerKm;
}
Date Vehicle::getPUCExpirationDate() const
{
return this->PUCExpirationDate;
}
void Vehicle::setPricePerKm( double newprice)
{
this->pricePerKm= newprice;
}
string Vehicle::getVehicleTypeName() const
{
switch(this->type)
{
case VehicleType:: bike:
return "bike";
case VehicleType:: car:
return "car";
case VehicleType:: towera:
return "Tower";
default:
return " ";
}
}
void Vehicle::display() const
{
cout<< "Vehicle Details :"<<endl;
cout<< "Registration Number : "<< this->registrationnumber<<endl;
cout<< "Vehicle Type : "<< this->type<<endl;
cout<< "No of seats : "<< this->seats<<endl;
cout<< "Company Name : "<< this->companyname<<endl;
cout<< "Price PER Km : "<< this->pricePerKm<<endl;
cout<< "PUC ExpirationDate : "<< this->PUCExpirationDate.toString()<<endl;
}
string Vehicle::toString() const
{
stringstream ss;
ss<<recordID<< DELIMETER<< registrationnumber<< DELIMETER<< type<< DELIMETER<< seats<< DELIMETER<< companyname<< DELIMETER
<< to_string(pricePerKm)<< DELIMETER<< PUCExpirationDate.toString();
return ss.str();
}
void Vehicle ::setDataForm(Storable *s)
{
Vehicle *v = dynamic_cast<Vehicle *> (s);
if(v)
{
this->registrationnumber= v->registrationnumber;
this->type= v->type;
this->companyname= v->companyname;
this->seats= v->seats;
this->pricePerKm = v->pricePerKm;
this->PUCExpirationDate= v->PUCExpirationDate;
}
}
Template Table header file
#define table_h
#include "storable.cpp"
#include "Vehicle.h"
#include "error.cpp"
#include <vector>
#include<string>
#include <fstream>
using namespace std;
template <class T> class Table {
private:
string fileName;
fstream fileStream;
vector<Storable *> * records = NULL;
T * getRefOfRecord(long recordID) const throw(IOError);
void writeToFile () throw(IOError);
T * addNewRecord (T data) const throw (IOError);
void updateRecord (T updateRecord) const throw (IOError);
public:
Table(string fileName) throw (MemoryError);
~Table();
long getNextRecordId() const;
const T* const getRecordForld(long recordId) const throw(IOError);
friend class Database;
};
#endif // table_h
Template table .cpp
#include "Table.h"
#include<iostream>
using namespace std;
template <class T> Table<T> ::Table(string fileName)
throw(MemoryError)
{
this->fileName = fileName;
this->records = new vector<Storable *> ();
if(!this->records)
{
throw MemoryError();
}
}
template <class T> long Table<T> ::getNextRecordId() const
{
return this->records->size()+1;
}
template <class T> T* Table<T> ::addNewRecord (T record) const throw (IOError)
{
T *newRecord = new T(record);
if(!newRecord)
{
throw new MemoryError();
}
newRecord->recordId = this->getNextRecordId();
this->records->push_back(newRecord);
try
{
this->writeToFile();
}
catch(IOError error)
{
this->records->pop_back();
delete newRecord;
throw;
}
return newRecord;
}
template <class T> void Table<T> ::updateRecord(T updateRecord) const throw(IOError)
{
for(auto & record:*this->records)
{
if(record->getRecordID()== updateRecord.getRecordID())
{
T * ptr = dynamic_cast<T*> (record);
if(ptr)
{
T oldRecord = T(* ptr);
record->setDataFrom(&updateRecord);
try
{
this->writeToFile();
return;
}
catch(IOError error)
{
record->setDataFrom (&oldRecord);
throw;
}
}
}
}
throw MemoryError();
}
template <class T> void Table<T> ::writeToFile() throw (IOError)
{
this->fileStream.open(fileName,ios::out | ios::trunc);
if(!this->fileStream)
{
throw IOError();
}
for(auto & record: *records)
{
fileStream <<record->toString()<<endl;
}
this->fileStream.close();
}
template <class T> const T* const Table<T> ::getRecordForld(long recordId) const throw(IOError)
{
try
{
return this->getRefOfRecord(recordId);
}
catch(IOError)
{
throw;
}
}
template <class T> T* Table<T> ::getRefOfRecord(long recordId) const throw (IOError)
{
for(auto &record :*records)
{
if(record->getRecordID()== recordId)
{
return dynamic_cast<T*> (record);
}
}
throw IOError();
}
template <class T> Table<T> ::~Table()
{
for(auto & record : *this->records)
{
delete dynamic_cast<T*> (record);
}
this->records->clear();
this->records->shrink_to_fit();
delete this->records;
}
the template class working fine with the other class such as user or trip but with vehicle class I am getting this error
give the error invalid abstract parameter type 'Vehicle'
I am stuck in this place two three day ago I terid but didn't find any clue !!
I saved objects to file and while reading them back i want to write it content to output stream. I did add operator overloading for it friend std::ostream& operator<<(std::ostream& out, T& c) but how to do it in correct way?
#include <iostream>
#include <fstream>
class MySpecificClass {
std::string data;
unsigned int x;
unsigned int y;
unsigned int z;
public:
MySpecificClass(): data(""), x(0), y(0), z(0) {}
MySpecificClass(std::string s, unsigned int xx, unsigned int yy, unsigned zz) : data(s), x(xx), y(yy), z(zz) {}
std::string Print() {
std::string s = "data: " + data + "\tx=" + std::to_string(x) + ",\ty=" + std::to_string(y) + ",\tz=" + std::to_string(z);
return s;
}
};
template <class T>
class IFileClass {
public:
IFileClass(std::string f) : fileName(f) {}
virtual void save(T& c) = 0;
virtual void read(T& c) = 0;
protected:
std::string fileName;
std::ofstream fout;
std::ifstream fin;
};
template <class T>
class FileWithClass : public IFileClass<T> {
public:
FileWithClass(std::string fn) : IFileClass<T>(fn) {
std::cout << "FileWithClass constructor" << std::endl;
}
friend std::ostream& operator<<(std::ostream& out, T& c) {
out << c.Print();
return out;
}
void save(T& c) override {
if (this->fileName == "")
throw new std::runtime_error("path is empty");
this->fout.open(this->fileName, std::ofstream::app);
if (this->fout.is_open()) {
this->fout.write((char*)&c, sizeof(T));
this->fout.close();
std::cout << "saved" << std::endl;
} else {
std::cout << "File open error" << std::endl;
}
}
void read(T& c) override {
if (this->fileName == "")
throw new std::runtime_error("path is empty");
this->fin.open(this->fileName);
if (this->fin.is_open()) {
while (this->fin.read((char*)&c, sizeof(T))) {
std::cout << c << std::endl;
}
this->fin.close();
} else {
std::cout << "File open error" << std::endl;
}
}
};
int main() {
MySpecificClass msc = {"My text", 1, 2, 3};
FileWithClass<MySpecificClass> fsv = {"test.txt"};
fsv.save(msc);
fsv.read(msc);
}
In line std::cout << c << std::endl; I get a compile error:
main.cpp|71|error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'MySpecificClass')
Basically this, outside of your class definition:
std::ostream& operator<<(std::ostream& out, MySpecificClass& c) {
out << c.Print();
return out;
}
You don't need to add the friend function definition, because you are not using any private members in your operator<<. And if you were, you would actually need to declare it friend in MySpecificClass, and not your template, because your template class has no access to MySpecificClass private data.
Error
e/c++/v1/algorithm:642:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/utility:321:9: error:
field type 'Space' is an abstract class
_T2 second;
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/map:624:16: note:
Question
How can I define a std::vector of type Space which is an abstract class and then fill this vector with instances of the derived classes Empty, Snake, Ladder.
Context
I know abstract classes in C++ can not be instantiated. Instead I've read in several posts on this and other sites that you can create a collection of an abstract type if it the type is defined as a star * pointer or any of the <memory> managed pointer data types like std::unqiue_ptr<T>. I've tried to used shared_ptr<Space> in my case, but still unable to define the collection properly. I am compiled my code using g++ -std=c++17 main.cpp && ./a.out.
Code
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <map>
#include <memory>
#include <typeinfo>
#include <queue>
#include <string>
#include <vector>
class Player
{
private:
int m_current_space = 1;
public:
Player() {}
void role_dice() {
m_current_space += floor( (rand()%10 + 1) / 3 );
}
int const get_current_space() {
return m_current_space;
}
void set_current_space(int current_space) {
m_current_space = current_space;
}
};
class Space
{
protected:
int m_id;
std::vector<Space> m_paths;
public:
Space() {} // requied to use [] operator in map
Space(int id) : m_id(id) {}
void add_path(Space& s) {
m_paths.push_back(s);
}
int get_id() {
return m_id;
}
virtual std::string class_type() = 0;
};
class Empty : public Space
{
public:
Empty(int id) : Space(id) {}
std::string class_type() {
return "Empty";
}
};
class Ladder : public Space
{
public:
Ladder(int id) : Space(id) {}
virtual void event(Player& p) {
p.set_current_space(1);
}
std::string class_type() {
return "Ladder";
}
};
class Snake : public Space
{
public:
Snake(int id) : Space(id) {}
virtual void event(Player& p) {
p.set_current_space(4);
}
std::string class_type() {
return "Snake";
}
};
class Board
{
private:
std::map<int, Space> m_board;
public:
void add_space(Space& s) {
m_board[s.get_id()] = s;
}
void draw_board() {
int i = 1;
for(auto const& [space_key, space] : m_board) {
if(i%3 == 0) {
std::cout << "○\n";
}
else if(typeid(space) == typeid(Snake)) {
std::cout << "○-";
}
else {
std::cout << "○ ";
}
++i;
}
}
void update_player_on_board(int position) {
int i = 1;
for(auto const& [space_key, space] : m_board) {
if(i%3 == 0) {
if (space_key == position) {
std::cout << "●\n";
}
else {
std::cout << "○\n";
}
}
else if(typeid(space) == typeid(Snake)) {
std::cout << "○-";
}
else {
if (space_key == position) {
std::cout << "● ";
}
else {
std::cout << "○ ";
}
}
++i;
}
}
const std::map<int, Space> get_board() {
return m_board;
}
friend std::ostream &operator<<(std::ostream& os, const Board& b) {
return os;
}
};
class GameStateManager
{
private:
std::string m_state = "game over";
bool m_playing = false;
public:
std::string const get_state() {
return m_state;
}
void set_state(std::string state) {
m_state = state;
}
};
int main()
{
std::cout << "Welcome to Bowser's 9 board game\n";
std::cout << "Start? y(yes) n(no)\n";
GameStateManager game_manager;
game_manager.set_state("playing");
auto space1 = std::make_shared<Space>(1);
auto space2 = std::make_shared<Space>(2);
auto space3 = std::make_shared<Space>(3);
auto space4 = std::make_shared<Space>(4);
auto space5 = std::make_shared<Space>(5);
auto space6 = std::make_shared<Space>(6);
auto space7 = std::make_shared<Space>(7);
auto space8 = std::make_shared<Space>(8);
auto space9 = std::make_shared<Space>(9);
std::vector<std::shared_ptr<Space>> v {
space1, space2, space3,
space4, space5, space6,
space7, space8, space9
};
Board bowsers_bigbad_laddersnake;
for(int i = 0; i < 10; ++i) {
bowsers_bigbad_laddersnake.add_space(*(v[i]));
}
bowsers_bigbad_laddersnake.draw_board();
Player mario;
int turn = 0;
while(game_manager.get_state() == "playing") {
std::cin.get();
std::cout << "-- Turn " << ++turn << " --" << '\n';
mario.role_dice();
bowsers_bigbad_laddersnake.update_player_on_board(mario.get_current_space());
if (mario.get_current_space() >= 9) {
game_manager.set_state("game over");
}
}
std::cout << "Thanks a so much for to playing!\nPress any key to continue . . .\n";
std::cin.get();
return 0;
}
You seem to have removed a lot of code to get into details here.
Have a Space pointer (smart or raw). Instantiate the specific space that you want, point to it with your pointer of type Space. Example std::shared_ptr<Space> pointerToSpace = std::make_shared<Snake> ("I'm a snake"); Now, without loss of generality, you can print the contents (of concrete type) with just the pointer to the space pointerToSpace->class_type(). Yes, you can have a collection of shared_ptrs in a container.
I need to use a for_each function to call the print function of each object in the list of objects shapeList. When I put function output as the final parameter of for_each, I get a "cannot determine which instance of overloaded function "output" is intended.
void output(Point* point)
{
point->print();
}
This is my output function for for_each
for_each(shapeList.begin(), shapeList.end(), output);
The for_each statement
I have looked at other solutions that involve using binds and lambdas, but this is a class assignment and I cannot use those methods.
Any help is greatly appreciated.
#include <iostream>
#include <string>
#include <fstream>
#include <list>
#include <algorithm>
#define sz 12
using namespace std;
class Point
{
private:
int x, y;
public:
Point() { }
Point(int a, int b)
:x(a), y(b) { }
// print function is pure virtual and that makes class Point an abstract class
// a pure virtual function can have prototype only without definition
// an abstract class can't be instantiated
// its derived class must override this function in order to be a real class
virtual void print() const = 0;
};
void Point::print() const
{
cout << "\nPoint: ( "
<< x
<< " , "
<< y
<< " )";
}
///////////////////////////////////////////////////////////////////
class Circle : public Point
{
private:
int radius;
public:
Circle() : Point() { }
Circle(int a, int b, int c)
:Point(a, b), radius(c) { }
virtual void print() const;
};
void Circle::print() const
{
cout << "\nCenter of the Circle is at: ";
Point::print();
cout << "\nRadius of the Circle is: "
<< radius;
}
/////////////////////////////////////////////////////////////////////
class Cylinder : public Circle
{
private:
int height;
char color[sz];
public:
Cylinder() { }
Cylinder(int a, int b, int r, int h, char clr[])
: Circle(a, b, r), height(h)
{ strcpy(color, clr); }
virtual void print() const;
};
void Cylinder::print() const
{
Circle::print();
cout << "\nHeight of Cylinder is: "
<< height
<< "\nColor of Cylinder is: "
<< color
<< endl;
}
void load_list(list<Point*>&, char*); //
void output(Point*&);
///////////////////////////////////////////////////////////////
int main()
{
char clr[10];
list<Point*> shapeList;////
load_list(shapeList, clr);
for_each(shapeList.begin(), shapeList.end(), output);
return 0;
}
void load_list(list<Point*>& ptList, char *ch)
{
char type;
int x, y, r, h;
ifstream infile("shapes.txt");
if (!infile)
{
cout << "\nCan not open input file.";
exit(1);
}
infile >> type;
while (infile)
{
if (type == 'c')
{
infile >> x >> y >> r;
ptList.push_back(new Circle(x,y,r));
}
else if (type = 'l')
{
infile >> x >> y >> r >> h >> ch;
ptList.push_back(new Cylinder(x, y, r, h, ch));
}
infile >> type;
}
}
void output(Point* point)
{
point->print();
}
You declare the function to take a pointer by reference(?) And the implementation takes a pointer.
I want to define a container in the base class, which contains function obj or anything that can make my purpose happen. These function obj can call derived classes' functions. they all take same parameters.
#include <vector>
#include <functional>
#include <iostream>
class Foo {
Foo() {}
virtual ~Foo(){}
virtual void init()
{ registerCallback(0, &Foo::print_ori ); }
void print_ori(int i) const { std::cout << i << '\n'; }
void registerCallback(int key, ??? cb ) // NOT SURE HOW TO DEFINE THIS
{
callbacks[key] = cb;
}
void runCallbacks(int key, int n)
{
auto i = callbacks.find(key);
if (i != callbacks.end()) {
(*i)(*this, n);
}
}
std::map<int, std::function<void(const Foo&, int) > > callbacks; // obviously, it's wrong. how to fix it?
};
struct Foo2 : public Foo {
Foo2(int num) : Foo(num) {}
virtual void init()
{
Foo::init();
registerCallback(11, &Foo2::print1 );
registerCallback(12, &Foo2::print2 );
}
void print1(int i) const { std::cout << " - Foo2.p1 - " << i << endl; }
void print2(int i) const { std::cout << " - Foo2.p2 - " << i << endl; }
};
int main()
{
Foo* obj = new Foo2();
obj->init();
obj->runCallbacks(12, 456);
}
Here's a way to achieve what your code looks like it's trying to do, without using function pointers:
class Foo {
Foo() {}
virtual ~Foo(){}
void print_ori(int i) const { std::cout << i << '\n'; }
virtual void do_runCallbacks(int v)
{
}
void runCallbacks()
{
print_ori(3)
do_runCallBacks(3);
}
};
struct Foo2 : public Foo {
Foo2(int num) : Foo(num) {}
void do_runcallbacks(int v)
{
print1(v);
print2(v);
}
void print1(int i) const { std::cout << " - Foo2.p1 - " << i << endl; }
void print2(int i) const { std::cout << " - Foo2.p2 - " << i << endl; }
};
int main()
{
Foo* obj = new Foo2();
obj->runCallbacks();
}
Now, there may well be reasons to do this completely differently, but I don't see why you should need both virtual functions and inheritance, AND function objects/function pointers. That seems quite wrong to me ("smells bad")
Edit:
Here's something I came up with, that solves the type of problem you describe after edits of the original question.
#include <iostream>
#include <map>
using namespace std;
class event_interface
{
public:
virtual void action(int n) = 0;
};
class event_manager
{
public:
event_manager(int n) : num(n) {}
void register_event(int key, event_interface *eh)
{
handlers[key] = eh;
}
void callback(int key)
{
auto h = handlers.find(key);
if (h != handlers.end())
{
h->second->action(num);
}
}
private:
map<int, event_interface *> handlers;
int num;
};
class handler1 : public event_interface
{
public:
void action(int n) { cout << "in handler1::action. n=" << n << endl; }
};
class handler2 : public event_interface
{
public:
handler2(int n) : data(n) {}
void action(int n)
{
cout << "in handler2::action. n=" << n
<< " data = " << data << endl;
}
private:
int data;
};
class multihandler
{
private:
class handler3: public event_interface
{
public:
void action(int n) { cout << "in handler3::action. n=" << n << endl; }
};
class handler4: public event_interface
{
public:
handler4(multihandler *m) : mh(m) {}
void action(int n)
{
cout << "in handler4::action. n=" << n
<< " data = " << mh->data << endl;
}
private:
multihandler* mh;
};
public:
multihandler(event_manager& em) : h4(this)
{
em.register_event(62, &h3);
em.register_event(63, &h4);
data = 42;
}
private:
handler3 h3;
handler4 h4;
int data;
};
int main()
{
event_manager mgr(3);
handler1 h1;
handler2 h2(77);
multihandler mh(mgr);
mgr.register_event(12, &h1);
mgr.register_event(13, &h2);
int evts[] = { 12, 63, 62, 13, 18 };
for(auto i : evts)
{
cout << "Event: " << i << endl;
mgr.callback(i);
}
}