I am trying to implement a naive File System.
I have this class
class BaseFile {
private:
string name;
public:
BaseFile(string name);
string getName() const;
void setName(string newName);
bool operator < (const BaseFile& str) const;
bool operator > (const BaseFile& str) const;
virtual int getSize() = 0;
};
and the subclass
class Directory : public BaseFile {
private:
vector<BaseFile*> children;
Directory *parent;
public:
Directory(string name, Directory *parent); r
Directory *getParent() const;
void setParent(Directory *newParent);
void removeFile(string name);
void removeFile(BaseFile* file);
void sortByName();
bool SortSize(BaseFile& a , BaseFile& b);
void sortBySize();
vector<BaseFile*> getChildren(); n
int getSize();
string getAbsolutePath();
};
I need to sort the vector<BaseFile*> children once by the attribute size by activating the function SortBySize().
And by name by the function SortByName().
I cant use sort algorithm I want to use std::sort()
For the names I overloaded the operators < > and for the numbers(size) I want to define a custom comparison function.
I defined the function in the class Directory. I tried to make is static it didn't work
bool Directory::SortSize(BaseFile& a , BaseFile& b)
{
return (a.getSize() < b.getSize());
}
but when I use std::(children.begin(), children.end(), sortSize)
I get "invalid use of non-static member function".
Any help?
To sort by size using a lambda expression:
vector<BaseFile*> files;
std::sort(files.begin(), files.end(),
[](const BaseFile* a, const BaseFile* b)
{ return a->getSize() < b->getSize(); });
Related
How can I copy all the objects to another set of objects. I created a temporary object so I can add the current "robot" to the "robotSquad". I am trying to dynamically add it
I am new to the concept of operator overloading, I might have the wrong assumption on what I'm doing. Im using the += operator, making a temp if there is no space in "robotSquad" adding it to temp then copying it to the original robotSquad named r_robot.
I could possibly be doing all this wrong, need help Thanks!
RobotSquad& RobotSquad::operator+=(const Robot& p_robot) {
if (count <= sizeof(r_robots)) {
//how do i copy?
RobotSquad temp[count+1];
temp[count]=p_robot;
for(int i=0 ;i<=sizeof(r_robots);i++){
temp[i]=r_robots[i];
}
} else {
this ->r_robots[count]=p_robot;
}
count++;
return *this;
}
class RobotSquad {
char* name ;
Robot *r_robots;
int count;
public:
//constructor
RobotSquad();
RobotSquad(Robot* , int, char* p_name= "No name");
~RobotSquad();
//getters
char* getName();
Robot* getRoster();
int getCount();
//setters
char setName();
Robot setRobot();
int setCount();
//other
RobotSquad& operator+=(const Robot&);
private:
void setEmpty();
};
With std, it could be:
class RobotSquad {
std::vector<Robot> robots;
std::string name;
public:
//constructor
RobotSquad() = default;
explicit RobotSquad(const std::vector<Robot>& robots,
const std::string& name= "No name")
: robots{robots}, name{name}
{}
~RobotSquad() = default;
RobotSquad& operator+=(const Robot& robot)
{
robots.push_back(robot);
return *this;
}
// ...
};
class cat
{public:
void dog(int ID, char *value) // int ID I'd like to be the index array it was called from?
{
debug(ID, value);
}
}
cat cats[18];
cats[1].dog("value second arg, first arg auto filled from index array");
I want something similar to this.
include <vector>
class CatArray;
class Cat {
// This line means that the CatArray class can
// access the private members of this class.
friend class CatArray;
private:
static int ID;
public:
void dog(const char* value) {
// Use ID here any way you want.
}
};
int Cat::ID = 0;
class CatArray {
private:
std::vector<Cat> cats;
public:
explicit CatArray(unsigned int size) : cats(size) {}
Cat& operator [](unsigned int index) {
Cat::ID = index;
return cats[index];
}
};
But a little different. There are 18 Clients in a game and i need to basically do this. for eg, "Client 4 Chooses an option and the option gets called through the array index and than that way client 4 will call the function with the function holding the index 4"
Then cats[1] is not really a Cat object but a CatWithIndex object:
class Cat {
public:
void dog(size_t index,const char* value);
};
class CatWithIndex {
size_t index_;
const Cat &cat_;
public:
CatWithIndex(size_t index, const Cat &cat): index_(index), cat_(cat) {}
void dog(const char* value) {
cat_.dog(index_,value);
}
};
class CatArray {
private:
std::vector<Cat> cats;
public:
Cat& operator [](unsigned int index) {
Cat::ID = index;
return CatWithIndex(index,cats[index]);
}
};
I've been assigned the following template:
#include <map>
template <typename T>
class Catalog {
struct Item {
//..
};
std::map<int, Item*> items;
public:
Catalog(void);
Catalog(const Catalog&);
~Catalog(void);
bool IsEmpty(void) const;
int Size() const;
void Add(T*);
T* Remove(T*);
T* Find(T*);
typedef void (T::*pFunc) (const T&);
void Inspection(pFunc) const;
};
Next, there is an abstract Product class and three subclasses:
class Product {
protected:
unsigned int _id;
string _name;
public:
Product(const int& id, const string& name) : _id(id), _name(name) {};
virtual void Action(const Product& p) = 0;
virtual int hashCode() {
return _id*100;
};
unsigned int getId(void) const {return _id;};
string getName(void) const {return _name;};
};
class ProductA : public Product {
public:
ProductA(const int& id, const string& name) : Product(id, name) {};
virtual void Action(const Product& p) {
cout << "ahoj" << endl;
};
};
Finally, class ProductsCatalog that handles a Catalog instance:
class ProductsCatalog {
Catalog<Product> catalog;
public:
//..
void CatalogInspection(void) const {
catalog.Inspection(&Product::Action);
}
};
What I have trouble with is the Inspection method:
template <typename T> void Catalog<T>::Inspection(pFunc p) const {
for (std::map<int, Item*>::const_iterator it=items.begin(); it!=items.end(); ++it) {
it->second->Product->*p(*(it->second->Product));
}
};
I am getting the following error:
error C2064: term does not evaluate to a function taking 1 arguments
I've tried everything I could think of, without success. The following works as intended, but is obviously not abstract enough:
it->second->Product->Action(*it->second->Product);
Did you try
(it->second->Product->*p)(*(it->second->Product));
for calling the method?
The thread Calling C++ class methods via a function pointer seems to be related.
My issue is :
I define class (generator) inside of which I define a forward nested structs (topics and it_set).
I make the declaration of this nested class inside the .cpp file.
After this I declare a second class (ImageGenerator) which is an inheritence of generator.
I get an issue when I try inside of the declaration file of ImageGenerator.
Is there anyway to make that possible ?
My codes are these :
<i>
//base.hpp
</i>
class generator{
protected:
struct topics;
struct it_set;
NodeHandle _nh;
cv::Ptr<topics> _topics;
cv::Ptr<it_set> _set;
cv::Mat _data;
public:
generator(ros::NodeHandle&,const std::string&,const std::string&,const std::string&);
virtual ~generator(void);
bool ok(void)const;
protected:
virtual void grab(void) = 0;
};
<i>
// base.cpp
</i>
static void cam_from_sub(const std::string& _subscriber,std::string& _cam){
std::stringstream str;
std::vector<std::string> words;
std::string tmp;
for(std::string::const_iterator it = _subscriber.begin();it != _subscriber.end();it++)
(*it != '/')?(str<<*it):(str<<std::endl);
while(!str.eof()){
str>>tmp;
words.push_back(tmp);
tmp.clear();
}
words.pop_back();
for(std::vector<std::string>::iterator it = words.begin(); it != words.end();it++){
_cam+=*it+std::string("/");
it->clear();
}
words.clear();
_cam+= std::string("camera_info");
}
struct generator::topics{
std::string _publisher;
std::string _subscriber;
std::string _camera_info;
topics(const std::string& _pub,const std::string& _sub,const std::string& _cam):_publisher(_pub),_subscriber(_sub),_camera_info(_cam){}
topics(const std::string &_pub, const std::string &_sub):_publisher(_pub),_subscriber(_sub){cam_from_sub(_subscriber,_camera_info);}
~topics(void){}
};
struct generator::it_set{
image_transport::ImageTransport _it;
image_transport::SubscriberFilter _is;
image_transport::Publisher _pb;
message_filters::Subscriber<sensor_msgs::CameraInfo> _cam_info;
it_set(NodeHandle& _nh,cv::Ptr<generator::topics>& _topics):_it(_nh),_is(_it,_topics->_subscriber,1),_cam_info(_nh,_topics->_camera_info,1){ this->_pb = this->_it.advertise(_topics->_publisher,1);}
};
generator::generator(NodeHandle & nh, const std::string & subscribe, const std::string & publish, const std::string & camera_info):_nh(nh),_topics(new topics(publish,subscribe,camera_info)),_set( new it_set(_nh,_topics)){}
generator::~generator(void){ _set.release(); _topics.release();}
bool generator::ok(void)const{ return this->_nh.ok();}
<i>
// image.hpp
</i>
class ImageGenerator : public generator{
private:
NodeHandle _nh;
static bool _sht;
bool _first_sht;
bool _is_sub;
public:
typedef void(*function_type)(const cv::Mat&,cv::Mat&);
private:
function_type _fun;
virtual void callback(const sensor_msgs::ImageConstPtr&);
virtual void grab(void);
public:
ImageGenerator(const NodeHandle&,const std::string&,const std::string&,const std::string&,function_type);
~ImageGenerator(void);
void operator>>(cv::Mat&);
void operator<<(const cv::Mat&);
};
<i>
// image.cpp
</i>
bool ImageGenerator::_sht = false;
void ImageGenerator::grab(void){
if(!this->_is_sub)
this->_set->_is.registerCallback(boost::bind(&ImageGenerator::callback,this,_1));
ros::CallbackQueue* mloop = ros::getGlobalCallbackQueue();
while(!this->_sht)
mloop->callAvailable(ros::WallDuration(0.1f));
this->_sht = true;
mloop = NULL;
this->_is_sub = true;
}
void ImageGenerator::callback(const sensor_msgs::ImageConstPtr &msg){
cv_bridge::CvImagePtr cv_ptr;
cv_ptr = cv_bridge::toCvCopy(msg);
this->_data = cv_ptr->image;
}
ImageGenerator::ImageGenerator(const NodeHandle & nh, const std::string & subscribe, const std::string & publish, const std::string & camera_info, function_type fun):_nh(nh),base::generator(_nh,subscribe,publish,camera_info),_fun(fun){ this->grab();}
ImageGenerator::~ImageGenerator(void){}
The issue which I want to solve is at
void ImageGenerator::grab(void)
It's :
this->_set->_is.registerCallback(boost::bind(&ImageGenerator::callback,this,_1));
the compiler answer :
error invalid use of incomplete type generator::it_set
The type is incomplete because the compiler hasn't seen the definition of that struct.
If you want to use the structs in subclasses of generator, you need to move their definitions inside the definition of generator in "base.hpp".
I am new to C++. Could you pls help me get rid of the errors:
error C2259: 'MinHeap' : cannot instantiate abstract class
IntelliSense: return type is not identical to nor covariant with return type "const int &" of overridden virtual function function
template <class T> class DataStructure {
public:
virtual ~DataStructure () {}
virtual bool IsEmpty () const = 0;
virtual void Push(const T&) = 0;
virtual const T& Top() const = 0;
virtual void Pop () = 0;
};
class MinHeap : public DataStructure<int>
{
private:
std::vector<int> A;
public:
bool IsEmpty() const
{
..
}
int Top() const
{
..
}
void Push(int item)
{
...
}
void Pop()
{
..
}
};
The problem is with const T& Top() vs. int Top(). The latter is different from the former, and thus not an override. Instead it hides the base class function. You need to return exactly the same as in the base class version: const int& Top() const.
The same problem exists for Push(), BTW.
try
class MinHeap : public DataStructure<int>
{
private:
std::vector<int> A;
public:
bool IsEmpty() const
{
..
}
const int& Top() const
{
..
}
void Push(const int& item)
{
...
}
void Pop()
{
..
}
};
Note that it is using const int& instead of int for Top and Push