I have the following code
#include<iostream>
using namespace std;
class operate
{
int x;
int y;
public:
operate(int _x, int _y):x(_x), y(_y)
{}
void add(const char* ch)
{
cout<<ch<<" "<<x+y;
}
void subtract(const char* ch)
{
cout<<ch<<" "<<x-y;
}
void multiply(const char* ch)
{
cout<<ch<<" "<<x*y;
}
};
int main()
{
void (operate::*fptr[3])(const char*);
operate obj(2,3);
fptr[0] = &(operate.add); //problem
fptr[1] = &(operate.multiply); //problem
fptr[2] = &(operate.subtract); //problem
(obj.*fptr[0])("adding");
(obj.*fptr[1])("multiplying");
(obj.*fptr[2])("subtracting");
}
It seems I am not assigning the member functions to function pointer array properly. How can I solve this. I'm using VS2010
The dot (member-of) operator is used for accessing members of an object. For classes and namespaces, you have to use the :: operator. Also, don't parenthesize, since & has lower precedence than :: and it's more readable like
fptr[0] = &operate::add;
This should do the job
void testFP()
{
typedef void (operate::*memFP)(const char*);
memFP fptr[3];
fptr[0] = &operate::add;
fptr[1] = &operate::multiply;
fptr[2] = &operate::subtract;
operate op(42, 42);
(op.*(fptr[0]))("adding");
}
Related
In the following code I made a template class, Its initialized in main function and I'm trying to assign char* as you can see below but It isn't working. I think the issue is in assign operator function I defined in Proxy class but I can't figure it out
#include <iostream>
using namespace std;
template <class T>
class Vector {
public:
T *p;
Vector(int size) {
p = new T[size];
}
class Proxy {
Vector &a;
int i;
public:
Proxy(Vector &a, int i) : a(a), i(i) {
}
void operator=(const T x) {
a.p[i] = x;
}
};
Proxy operator[](int i) {
return Proxy(*this, i);
}
};
int main() {
Vector<char *> sv1(2);
sv1[0] = "John";
sv1[1] = "Doe";
}
I'm getting following error;
I already tried setting parameter in assignment operator function to const, I also tried implicitly typecasting to T nothing has worked
Try this:
using namespace std;
template <class T>
class Vector {
public:
T* p;
int sz;
Vector(int size) {
p = new T[size];
sz = size;
}
template<class T>
class Proxy {
Vector<T>& v;
int i;
public:
Proxy(Vector<T>& vec, int index) :v(vec),i(index) { }
void operator= (const T val) { v.p[i] = val; }
};
Proxy<T> operator[](int index) { return Proxy<T>(*this, index); }
};
Your code will work with any basic type, (int, char, double) and pointers, but not, for example, with this:
int main() {
Vector<char*> sv1(2);
sv1[0] = "John";
sv1[1] = "Doe";
}
Firstly, the Vector points to a char*, not a string literal (const char*). You'd have to cast it using a C-style cast or a const_cast. Example:
int main() {
Vector<char*> sv1(2);
sv1[0] = const_cast<char*>("John"); //succeeds
sv1[1] = (char*)"Doe"; //succeeds
sv1[0] = "John"; //fails
sv1[1] = "Doe"; //fails
}
A string literal is always a const char* in C++.
You'll have same error writing code:
char * whatever = "something";
This code is absolutely wrong at least for string:
void operator=(const T x)
{
a.p[i] = x;
}
Step 1: allocate buffer;
Step 2: copy string to allocated buffer.
Your code is OK for primitives like char, int, etc. The following code should work:
int main() {
Vector<char> sv1(2);
sv1[0] = 'J';
sv1[1] = 'D';
}
I wanted to understand how the inline member variable work while accessing it through a const member variable.
Each time I try doing so, I get an error!
This is what I am trying
#include <iostream>
#include <string>
using namespace std;
class A{
public:
A()
{
_uuid = 0;
}
~A();
void setUUID(int n) { _uuid = n; }
inline int getUUID(){ return _uuid;} const
int getUUID1() const { return _uuid;}
int getUUIDsmart()const
{
return _uuid;
}
private:
int _uuid;
};
class B {
public:
B(){}
~B();
void fun1(const A *obj)
{
cout<<obj->getUUIDsmart()<<endl; //works fine
cout<<obj->getUUID1()<<endl; //works fine
cout<<obj->getUUID()<<endl; //error
A *obj1 = const_cast<A *>(obj);
cout<<obj1->getUUID()<<endl; //works fine
}
};
int main()
{
B *b = new B;
A *a = new A;
a->setUUID(12);
b->fun1(a);
}
I am able to get my code work through
const_cast
But I am interested in knowing why do i get an error in the inline function if I try accessing it through a const member function?
Update: FIX
My bad. I had the placement of const messed up!
Thanks to #bruno
inline int getUUID() const { return _uuid; }
//correct syntax. i placed the const at the end
[note : I use the first version of the question]
you place wrongly your const :
inline int getUUID(){ return _uuid;} const
int getUUID1(){ return _uuid;} const
int getUUIDsmart()const
is in fact
inline int getUUID(){ return _uuid;}
const int getUUID1(){ return _uuid;}
const int getUUIDsmart()const
I just moved the const on the right line for readability reason
You wanted
inline int getUUID() const { return _uuid;}
int getUUID1() const{ return _uuid;}
in your version none of getUUID1 nor getUUID are const so you cannot apply them on a const instance
There is no link at all with the fact your methods are inline or not.
Note :
cout<<obj->getUUID1()<<endl; //works fine
it doesn't
So I'm using the STL priority_queue<> with pointers... I don't want to use value types because it will be incredibly wasteful to create a bunch of new objects just for use in the priority queue. So... I'm trying to do this:
class Int {
public:
Int(int val) : m_val(val) {}
int getVal() { return m_val; }
private:
int m_val;
}
priority_queue<Int*> myQ;
myQ.push(new Int(5));
myQ.push(new Int(6));
myQ.push(new Int(3));
Now how can I write a comparison function to get those to be ordered correctly in the Q? Or, can someone suggest an alternate strategy? I really need the priority_queue interface and would like to not use copy constructors (because of massive amounts of data). Thanks
EDIT: Int is just a placeholder/example... I know I can just use int in C/C++ lol...
You can explicitly specify which comparator your queue should use.
#include <iostream>
#include <sstream>
#include <functional>
#include <vector>
#include <queue>
class Int {
public:
Int(int val) : m_val(val) {}
int getVal() { return m_val; }
bool operator<(const Int &other) const { return m_val < other.m_val; }
private:
int m_val;
};
template<typename Type, typename Compare = std::less<Type> >
struct pless : public std::binary_function<Type *, Type *, bool> {
bool operator()(const Type *x, const Type *y) const
{ return Compare()(*x, *y); }
};
int main(int argc, char *argv[]) {
std::priority_queue<Int*, std::vector<Int*>, pless<Int> > myQ;
for (int i = 1; i < argc; i++) {
std::stringstream ss(argv[i]);
int x;
ss >> x;
myQ.push(new Int(x));
}
for (; !myQ.empty(); delete myQ.top(), myQ.pop())
std::cout << myQ.top()->getVal() << std::endl;
return 0;
}
One option that will surely work is to replace Int* with shared_ptr<Int> and then implement operator< for shared_ptr<Int>
bool operator<(const shared_ptr<Int> a, const shared_ptr<Int> b)
{
return a->getVal() < b->getVal();
}
An integer is the same size as a pointer on 32 bit systems. On 64 bit systems, a pointer will be twice as big. Therefore, it is simpler/faster/better to use regular integers.
This is part of a C++ program based on the Alternative Vote electoral method, using VS2015. I have a class for Party
#pragma once
#ifndef _PARTY_H
#define _PARTY_H
#include <string>
class Party {
public:
Party();
~Party();
Party(std::string n, int pos);
void reset();
void upTotal();
int getPosition();
std::string getName();
int getVotes();
private:
std::string name;
int votes;
int position;
};
#endif
and
#include <iostream>
#include "Party.h"
using namespace std;
Party::Party() {}
Party::~Party() {}
Party::Party(string n, int p) {
name = n;
position = p;
}
void Party::reset() {
votes = 0;
}
void Party::upTotal() {
votes += 1;
}
int Party::getPosition() {
return position;
}
string Party::getName() {
return name;
};
int Party::getVotes() {
return votes;
}
I tried to sort on votes received using (calculated from ballot papers elsewhere in the program
void sortParties() {
sort(parties.begin(), parties.end(), [](const auto& a, const auto& b)
{
return a.getVotes() < b.getVotes();
});
}
which returned illegal operand errors. Moving the variables from private to public and writing the following did work
void sortParties() {
sort(parties.begin(), parties.end(), [](const auto& a, const auto& b)
{
return a.votes < b.votes;
});
}
which gets it working, but I want to write it with proper encapsulation using private variables and an accessor for votes. Do I need to overload somehow, or convert type?
You have the following functions defined:
int getPosition();
std::string getName();
int getVotes();
They should probably all be const; ie
int getPosition() const;
std::string getName() const;
int getVotes() const;
This will allow you to call the functions from your const object at
sort(parties.begin(), parties.end(), [](const auto& a, const auto& b)
So I'm using the STL priority_queue<> with pointers... I don't want to use value types because it will be incredibly wasteful to create a bunch of new objects just for use in the priority queue. So... I'm trying to do this:
class Int {
public:
Int(int val) : m_val(val) {}
int getVal() { return m_val; }
private:
int m_val;
}
priority_queue<Int*> myQ;
myQ.push(new Int(5));
myQ.push(new Int(6));
myQ.push(new Int(3));
Now how can I write a comparison function to get those to be ordered correctly in the Q? Or, can someone suggest an alternate strategy? I really need the priority_queue interface and would like to not use copy constructors (because of massive amounts of data). Thanks
EDIT: Int is just a placeholder/example... I know I can just use int in C/C++ lol...
You can explicitly specify which comparator your queue should use.
#include <iostream>
#include <sstream>
#include <functional>
#include <vector>
#include <queue>
class Int {
public:
Int(int val) : m_val(val) {}
int getVal() { return m_val; }
bool operator<(const Int &other) const { return m_val < other.m_val; }
private:
int m_val;
};
template<typename Type, typename Compare = std::less<Type> >
struct pless : public std::binary_function<Type *, Type *, bool> {
bool operator()(const Type *x, const Type *y) const
{ return Compare()(*x, *y); }
};
int main(int argc, char *argv[]) {
std::priority_queue<Int*, std::vector<Int*>, pless<Int> > myQ;
for (int i = 1; i < argc; i++) {
std::stringstream ss(argv[i]);
int x;
ss >> x;
myQ.push(new Int(x));
}
for (; !myQ.empty(); delete myQ.top(), myQ.pop())
std::cout << myQ.top()->getVal() << std::endl;
return 0;
}
One option that will surely work is to replace Int* with shared_ptr<Int> and then implement operator< for shared_ptr<Int>
bool operator<(const shared_ptr<Int> a, const shared_ptr<Int> b)
{
return a->getVal() < b->getVal();
}
An integer is the same size as a pointer on 32 bit systems. On 64 bit systems, a pointer will be twice as big. Therefore, it is simpler/faster/better to use regular integers.