Overloading [] operator c++ - c++

I am trying to overload the indexing operator for a c++ class but I am not able to do so. When I try to index my Matrix class, I get the following error:
error: cannot convert 'Matrix' to 'double*' in initialization
This error occurs on the 9th line of my main.cpp. Does it seem that the indexing does not seem to be recognized by the compiler?
Below is my code:
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <iostream>
using namespace std;
class Matrix
{
public:
/** Default constructor */
Matrix(unsigned int num_cols, unsigned int num_rows);
/** Default destructor */
virtual ~Matrix();
/** Access num_cols
* \return The current value of num_cols
*/
unsigned int getCols() { return _num_cols; }
/** Access num_rows
* \return The current value of num_rows
*/
unsigned int getRows() { return _num_rows; }
double operator[](unsigned int index);
protected:
private:
unsigned int _num_cols; //!< Member variable "num_cols"
unsigned int _num_rows; //!< Member variable "num_rows"
double ** _base;
};
#endif // MATRIX_H
Matrix.cpp
#include "Matrix.h"
Matrix::Matrix(unsigned int num_cols, unsigned int num_rows){
_num_cols = num_cols;
_num_rows = num_rows;
if(_num_cols > 0) {
_base = new double*[_num_cols];
for(unsigned int i = 0; i < _num_cols; i++) {
_base[i] = arr;
cout << _base[i] << endl;
}
}
}
double* Matrix::operator[](int index) {
if (index >= _num_cols) {
cout << "Array index out of bound, exiting";
exit(0);
}
return _base[index];
}
Matrix::~Matrix()
{
//dtor
}
main.cpp
#include <iostream>
#include "Matrix.h"
using namespace std;
int main()
{
Matrix * m = new Matrix(1,2);
double * d = m[1];
delete m;
return 0;
}

The declaration of the overloaded operator member function doesn't match the definition.
You defined the operator as:
double* Matrix::operator[](int index) {
But declared it as:
double operator[](unsigned int index);
The declaration should be:
double *operator[](int index);
Also, the problem with this line:
double * d = m[1];
Is that m is a pointer to a Matrix and the [] operator works on the class instance, not a pointer to it, so you need to dereference m:
double * d = (*m)[1];
Or you can define m as an instance of a Matrix:
Matrix m(1,2);
double * d = m[1];

Related

Why can't you define the instance structure of a derivable type in GObject

What I'm trying to imitate with GObject
Here's a simple C++ example:
#include <iostream>
using std::cout;
using std::endl;
class Matrix {
public:
Matrix (int rows, int cols) {
this->rows = rows;
this->cols = cols;
this->coeffs = 0;
};
int rows, cols;
double *coeffs;
};
class SymmetricMatrix final : public Matrix {
public:
SymmetricMatrix (int size) : Matrix (size, size) {
this->size = size;
this->nb_coeffs = size*(size-1)/2;
this->coeffs = new double[this->nb_coeffs]();
};
int size, nb_coeffs;
void print_self () {
for (int i=0; i<this->nb_coeffs; i++) {
cout << this->coeffs[i] << " ";
}
cout << endl;
};
};
int main () {
SymmetricMatrix S (6);
S.print_self ();
cout << S.cols << endl; // Access parent's public member variable !
return 0;
}
What I've got for now
I want to copy the C++ class structure but using GObject.
The problem is: I don't understand how I can define and inherit public variables for a derivable base class. Indeed, since the G_DECLARE_DERIVABLE_TYPE already defines one, I can't redefine it... Why is it one should not be able to do this ?
Here's what I have for now[^1]. As far as I understand, it isn't possible because GObject is not C++ and the general paradigms aren't the same.
tmatrix.h
#ifndef TMATRIX_H
#define TMATRIX_H
#include <glib-object.h>
#define T_TYPE_MATRIX t_matrix_get_type()
G_DECLARE_DERIVABLE_TYPE (TMatrix, t_matrix, T, MATRIX, GObject)
struct _TMatrixClass {
GObjectClass parent_class;
};
// struct _TMatrix {
// GObject parent_instance;
// gint nrows;
// gint ncols;
// gdouble *coeffs;
// };
/* Public function */
TMatrix *t_matrix_new (int ncols, int nrows);
#endif
tmatrix.c
#include "tmatrix.h"
G_DEFINE_TYPE (TMatrix, t_matrix, G_TYPE_OBJECT)
void t_matrix_class_init (TMatrixClass *class) {}
void t_matrix_init (TMatrix *instance) {}
TMatrix *t_matrix_new (gint ncols, gint nrows) {
TMatrix *matrix = g_object_new (T_TYPE_MATRIX, NULL);
// matrix->cols = ncols;
// matrix->rows = nrows
return matrix;
}
tsymmetricmatrix.h
#ifndef TSYMETRICMATRIX_H
#define TSYMETRICMATRIX_H
#include "tmatrix.h"
#include <glib-object.h>
struct _TSymmetricMatrix {
TMatrix parent_object;
// Public members
gint size;
};
#define T_TYPE_SYMMETRIC_MATRIX t_symmetric_matrix_get_type ()
G_DECLARE_FINAL_TYPE (TSymmetricMatrix, t_symmetric_matrix, T, SYMMETRIC_MATRIX, TMatrix)
/*Public class methods*/
void t_symmetric_matrix_print (TSymmetricMatrix *self);
/*Namespace public functions*/
TSymmetricMatrix *t_symmetric_matrix_new (gint size);
#endif
tsymmetricmatrix.c
#include "tsymmetricmatrix.h"
G_DEFINE_FINAL_TYPE (TSymmetricMatrix, t_symmetric_matrix, T_TYPE_MATRIX)
void t_symmetric_matrix_class_init (TSymmetricMatrixClass *class) {}
void t_symmetric_matrix_init (TSymmetricMatrix *instance) {}
void t_symmetric_matrix_print (TSymmetricMatrix *self) {
// print code
}
TSymmetricMatrix *t_symmetric_matrix_new (gint size) {
TSymmetricMatrix *matrix = g_object_new (T_TYPE_SYMMETRIC_MATRIX, NULL);
//
// I don't know what to do next ...
return matrix;
}
main.c
#include "tmatrix.h"
#include "tsymmetricmatrix.h"
int main () {
TSymmetricMatrix *A = t_symmetric_matrix_new (3);
t_symmetric_matrix_print(A);
return 0;
}
[^1]:Note: I know I should be using properties for setting/getting class variables. This is really just for the sake of learning.

Why am I getting a Link error when I try to overload an operator?

I'm doing a project exercise, where I'm revising a previous project of a class I created called Polynomial to use a link list (the original used arrays). The link list uses a template so that any type can be passed into it.
One of the problems I ran into with this project exercise is that I am trying to pass an object of type PolyNumber (from a class I made), and the link list bag I made has a function that compares any item (using ==) that is passed to it.
It works fine with regular types, such as int and string, but runs into problems with custom made object types. So I figured out how to overload the == operator in the PolyNumber class. By itself, it works when I test this class, but when I use this type with the Polynomial class with the Link List implementation, I get errors such as the following for each method in the Polynomial class:
Error LNK2005 "public: __thiscall PolyNumber::PolyNumber(int,int)" (??0PolyNumber##QAE#HH#Z) already defined in Polynomial.obj Project11
Here's my code for those files, but as you can see in the code, there are other files that go with this code, such as the LinkedBag for the link list object, but for space I just include these:
PolyNumber.h
#pragma once
class PolyNumber
{
public:
PolyNumber();
PolyNumber(int set_coefficent, int set_degree);
void setDegree(int set);
void setCoefficient(int set);
int getDegree();
int getCoefficient();
friend bool operator== (const PolyNumber& p1, const PolyNumber& p2);
friend bool operator!= (const PolyNumber& p1, const PolyNumber& p2);
private:
int degree;
int coefficient;
};
PolyNumber.cpp
#include "PolyNumber.h"
PolyNumber::PolyNumber()
{
coefficient = 0;
degree = 0;
}
PolyNumber::PolyNumber(int set_coefficent, int set_degree)
{
coefficient = set_coefficent;
degree = set_degree;
}
void PolyNumber::setDegree(int set)
{
degree = set;
}
void PolyNumber::setCoefficient(int set)
{
coefficient = set;
}
inline int PolyNumber::getDegree()
{
return degree;
}
inline int PolyNumber::getCoefficient()
{
return coefficient;
}
bool operator== (const PolyNumber& p1, const PolyNumber& p2)
{
return (p1.coefficient == p2.coefficient && p1.degree == p2.degree);
}
bool operator!= (const PolyNumber& p1, const PolyNumber& p2)
{
return !(p1 == p2);
}
Polynomial.h
#pragma once
#include "PolynomialInterface.h"
#include "LinkedBag.cpp"
#include "PolyNumber.cpp"
static const int POLYNOMIAL_SIZE = 10;
class Polynomial : public Polynomoal_Interface
{
public:
//Cunstructs am empty Polynomial
Polynomial();
//Copy constructor
Polynomial(Polynomial& copy);
/** Cunstructs a Polynomial with a client defined Polynomial
#param an array of non-negative integer coeffient that does not exceed POLYNOMIAL_SIZE, each coeffient in the array has a power that correspounds
to the respective value of the location of the ceffient in that array. */
Polynomial(int coeffient[POLYNOMIAL_SIZE], int size);
int degree();
int coefficient(int power);
bool changeCoefficient(int newCoefficient, int power);
private:
//static const int POLYNOMIAL_SIZE = 10;
//int polynomial[POLYNOMIAL_SIZE];
LinkedBag<PolyNumber> bag;
};
Polynomial.cpp
#include "Polynomial.h"
Polynomial::Polynomial()
{
}
Polynomial::Polynomial(Polynomial& copy)
{
std::vector<PolyNumber> copyFrom = copy.bag.toVector();
for (int i = 0; i < copyFrom.size(); i++)
{
bag.add(copyFrom[i]);
}
}
Polynomial::Polynomial(int coeffient[POLYNOMIAL_SIZE], int size)
{
for (int i = 0; i <= size; i++)
{
PolyNumber number = { coeffient[i], i + 1 };
bag.add(number);
}
}
int Polynomial::degree()
{
int max = 0;
std::vector<PolyNumber> result = bag.toVector();
for (int i = 0; i < result.size(); i++)
{
if (result[i].getDegree() > max)
{
max = result[i].getDegree();
}
}
return max;
}
int Polynomial::coefficient(int power)
{
int result = 0;
std::vector<PolyNumber> powerOf = bag.toVector();
for (int i = 0; i < powerOf.size(); i++)
{
if (powerOf[i].getDegree() == power)
{
result = powerOf[i].getCoefficient();
}
}
return result;
}
bool Polynomial::changeCoefficient(int newCoefficient, int power)
{
PolyNumber number = { newCoefficient, power };
int result = coefficient(power) + newCoefficient;
bag.remove(number);
number.setCoefficient(result);
bag.add(number);
return true;
}
You have #include "PolyNumber.cpp" instead of #include "PolyNumber.h".
That makes all the methods defined in PolyNumber.cpp to be included (and re-defined) in Polynomial.cpp.
The same will happen with LinkedBag.
Why are you including cpps?

Return pointer to array virtual template function

I would like to return an array to a pointer, in a virtual function that is a member of a derived class of a template class. In details, my classes definition is:
Sampler.h
#ifndef SAMPLER_H
#define SAMPLER_H
template <class T>
class Sampler
{
public:
virtual T getnumber()=0;
virtual T* simulation(int n)=0;
};
class UniformSampler:public Sampler<double>
{
public:
virtual double getnumber();
virtual double* simulation(int n);
UniformSampler(double a=0.0, double b=1.0);
private:
double low_bound;
double up_bound;
};
#endif
The class Sampler is a template class in order to be able to derive an other sampler with vectors later. The implementation is:
Sampler.cpp
#include "Sampler.h"
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
//Uniform
UniformSampler::UniformSampler(double a, double b)
{
low_bound=a;
up_bound=b;
}
double UniformSampler::getnumber()
{
int myrand=rand();
while((myrand==0)||(myrand==RAND_MAX)){myrand = rand(); } //We want a number in (0, RAND_MAX).
double myuni = myrand/static_cast<double>(RAND_MAX); //Create a number in (0,1).
return low_bound + myuni*(up_bound-low_bound);
}
double* UniformSampler::simulation(int n){
double simulations[n];
for(int i=0; i<n; i++){
simulations[i] = this->getnumber();
}
return simulations;
}
My problem is that, when I try to call this program in the main(), it looks like the assignment of the pointer doesn't work. Here is my main.cpp:
#include <iostream>
#include <math.h>
#include <cstdlib>
#include <time.h>
using namespace std;
#include "Sampler.h"
int main(){
srand(time(0));
int n=10;
double *unif = new double[n];
UniformSampler uni;
unif = uni.simulation(n);
for ( int i = 0; i < n; i++ ) {
cout << "*(p + " << i << ") : ";
cout << *(unif + i) << endl;
}
delete[] unif;
return 0;
}
When I run it, it doesn't print any of the elements that unif points to. I don't understand what is wrong there.
UniformSampler::simulation is twice wrong:
double simulations[n]; uses VLA extension, so not C++ standard compliant.
you return pointer on local variable, so dangling pointer.
Solution: use std::vector instead.
#include <vector>
template <class T>
class Sampler
{
public:
virtual ~Sampler() = default;
virtual T getnumber() = 0;
virtual std::vector<T> simulation(int n) = 0;
};
class UniformSampler:public Sampler<double>
{
public:
explicit UniformSampler(double a=0.0, double b=1.0);
double getnumber() overrid;
std::vector<double> simulation(int n) override
{
std::vector<double> res(n);
for (auto& val : res){
res = getnumber();
}
return res;
}
private:
double low_bound;
double up_bound;
};
int main(){
srand(time(0));
constexpr int n = 10;
UniformSampler uni;
auto unif = uni.simulation(n);
for (int i = 0; i < n; i++ ) {
std::cout << "p[" << i << "]: " << unif[i] << endl;
}
}

Issues creating a vector of class object in c++

I created the following class
#include "cliques.h"
#include "vector"
#include <iostream>
using namespace std;
cliques::cliques(){
}
cliques::cliques(int i) {
clique.push_back(i);
clique_prob = 1;
mclique_prob = 1;
}
cliques::cliques(const cliques& orig) {
}
cliques::~cliques() {
}
void cliques::addvertex(int i) {
clique.push_back(i);
}
double cliques::getclique_prob() const {
return clique_prob;
}
double cliques::getMaxclique_prob() const {
return mclique_prob;
}
void cliques::showVertices() {
for (vector<int>::const_iterator i = clique.begin(); i !=clique.end(); ++i)
cout << *i << ' ';
cout << endl;
}
vector<int> cliques::returnVector() {
return clique;
}
void cliques::setclique_prob(double i) {
clique_prob = i;
}
void cliques::setMaxclique_prob(double i) {
mclique_prob = i;
}
Here's the header file
#include "vector"
#ifndef CLIQUES_H
#define CLIQUES_H
class cliques {
public:
void addvertex(int i);
cliques();
cliques(int i);
cliques(const cliques& orig);
virtual ~cliques();
double getclique_prob() const;
double getMaxclique_prob() const;
void showVertices();
std::vector<int> returnVector();
void setclique_prob(double i);
void setMaxclique_prob(double i);
private:
float clique_prob;
float mclique_prob;
std::vector <int> clique;
};
#endif /* CLIQUES_H */
I want to create a vector of these objects in order to implement a heap
int main(int argc, char** argv) {
cliques temp(1);
cliques temp1(2);
temp.setclique_prob(0.32);
temp.setclique_prob(0.852);
temp.showVertices();
temp1.showVertices();
vector <cliques> max_heap;
max_heap.push_back(temp);
max_heap.push_back(temp1);
double x =max_heap.front().getclique_prob();
cout<<"prob "<<x<<endl;
cliques y = max_heap.front();
y.showVertices();
//make_heap (max_heap.begin(),max_heap.end(),max_iterator());
//sort_heap (max_heap.begin(),max_heap.end(),max_iterator());
return 0;
}
For reasons unknown to me none of my class functions work properly after i create my vector, meaning that while the following function works as intended
temp.showVertices()
the next one doesn't,
y.showVertices()
You miss implementation for
cliques::cliques(const cliques& orig) {
}
STL vector uses copy constructor inside when you add values to it. As your cliques class does not allocate any memory, you can just remove the copy constructor from the code and compiler will generate one for you.

expected an identifier c++

I am trying to write a class and I finally got it to compile, but visual studio still shows there are errors (with a red line).
The problem is at (I wrote #problem here# around the places where visual studio draws a red line):
1. const priority_queue<int,vector<int>,greater<int> #># * CM::getHeavyHitters() {
2. return & #heavyHitters# ;
3. }
And it says:
"Error: expected an identifier" (at the first line)
"Error: identifier "heavyHitters" is undefined" (at the second line)
The first problem I don't understand at all. The second one I don't understand because heavyHitters is a a member of CM and I included CM.
BTW, I tried to build. It didn't fix the problem.
Thanks!!!
The whole code is here:
Count-Min Sketch.cpp
#include "Count-Min Sketch.h"
CM::CM(double eps, double del) {
}
void CM::update(int i, int long unsigned c) {
}
int long unsigned CM::point(int i) {
int min = count[0][calcHash(0,i)];
return min;
}
const priority_queue<int,vector<int>,greater<int>>* CM::getHeavyHitters() {
return &heavyHitters;
}
CM::CM(const CM &) {
}
CM::~CM() {
}
int CM::calcHash(int hashNum, int inpt) {
int a = hashFunc[hashNum][0];
int b = hashFunc[hashNum][1];
return ((a*inpt+b) %p) %w;
}
bool CM::isPrime(int a) {
bool boo = true;
return boo;
}
int CM::gePrime(int n) {
int ge = 2;
return ge;
}
Count-Min Sketch.h
#pragma once
#ifndef _CM_H
#define _CM_H
using namespace std;
#include <queue>
class CM {
private:
// d = ceiling(log(3,1/del)), w = ceiling(3/eps)
int d,w,p;
// [d][w]
int long unsigned *(*count);
// [d][2]
int *(hashFunc[2]);
// initialized to 0. norm = sum(ci)
int long unsigned norm;
// Min heap
priority_queue<int,vector<int>,greater<int>> heavyHitters;
// ((ax+b)mod p)mod w
int calcHash(int hashNum, int inpt);
// Is a a prime number
bool isPrime(int a);
// Find a prime >= n
int gePrime(int n);
public:
// Constructor
CM(double eps, double del);
// count[j,hj(i)]+=c for 0<=j<d, norm+=c, heap update & check
void update(int i, int long unsigned c);
// Point query ai = minjcount[j,hj(i)]
int long unsigned point(int i);
const priority_queue<int,vector<int>,greater<int>>* getHeavyHitters();
// Copy constructor
CM(const CM &);
// Destructor
~CM();
};
#endif // _CM_H
>> is a single token, the right-shift (or extraction) operator. Some compilers don't recognize it correctly in nested template specialization. You have to put a space between the two angle brackets like this:
Type<specType<nestedSpecType> > ident;
^^^