Pointer on classelement and save the Pointer in a array - c++

this is my code:
class Node {
private:
unsigned number;
unsigned color;
public:
Knoten(unsigned int number = 0, unsigned int color = 0)
{}
void set_number(unsigned int a){
number = a;
}
void set_color(unsigned int b){
color = b;
}
unsigned int get_number(void){
return number;
}
unsigned int get_color(void){
return color;
}
void print(void){
cout << number << " " << color << endl;
}
};
int main(){
Node node1, node 2, node 3;
Knoten* n1,n2,n3;
n1=&node1;
n2=&node1;
n3=&node1;
node1.set_number(1);
node1.set_color(3);
node2.set_number(2);
node2.set_color(5);
node3.set_number(3);
node3.set_color(7);
node1.ausgabe();
node2.ausgabe();
node3.ausgabe();
Node* matrix[2][2];
return 0;
Ok, i want to save the pointer in the array.
Once they are in the array, how do I edit the properties of each Array elements.
For Example.
n1 is save in matrix[0][0].
and the color is change from 3 to 10.
How i do this.
Thanks

If I have correctly understood you and if do not take into account your invalid code then you can use expression
matrix[0][0]->set_color( 10 );
Or
if ( matrix[0][0]->get_color() == 3 ) matrix[0][0]->set_color( 10 );

Related

How to return structure array in C++

So I've been trying to implement Kruskal's algorithm, first I want to make clear the question is not related to the implementation of the algorithm. I've created one graph.hpp file, one kruskalsAlgo.hpp and main.cpp as follows respectively:
#pragma once
struct Edge
{
int source;
int destination;
int weight;
};
struct Graph
{
int V;
int E;
Edge* edge;
};
Graph* create_graph(int V, int E)
{
Graph* graph = new Graph;
graph -> V = V;
graph -> E = E;
graph -> edge = new Edge[E];
return graph;
}
#include <stdlib.h>
#include <tuple>
#include "../Graph/Graph.hpp"
class Kruskals_Algo
{
private:
struct subset
{
int parent;
int rank;
};
void make_set(subset*, int);
int find_set(subset*, int);
void _union(subset*, int, int);
public:
Edge* kruskal(Graph*);
void print_kruskals_MST(Edge*, int);
};
void Kruskals_Algo::make_set(subset* subsets, int V)
{
subsets[V].parent = V;
subsets[V].rank = 0;
}
int Kruskals_Algo::find_set(subset* subsets, int V)
{
if(subsets[V].parent != V)
subsets[V].parent = find_set(subsets, subsets[V].parent);
return subsets[V].parent;
}
void Kruskals_Algo::_union(subset* subsets, int x, int y)
{
int xroot = find_set(subsets, x);
int yroot = find_set(subsets, y);
if(subsets[xroot].rank < subsets[yroot].rank)
subsets[xroot].parent = yroot;
else if(subsets[xroot].rank > subsets[yroot].rank)
subsets[yroot].parent = xroot;
else
{
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}
inline int myComp(const void* a, const void* b)
{
Edge* a1 = (Edge*)a;
Edge* b1 = (Edge*)b;
return a1 -> weight > b1 -> weight;
}
Edge* Kruskals_Algo::kruskal(Graph* graph)
{
int V = graph -> V;
Edge result[V];
Edge* result_ptr = result;
int e = 0;
int i = 0;
qsort(graph -> edge, graph -> E, sizeof(graph -> edge[0]), myComp);
subset* subsets = new subset[(V * sizeof(subset))];
for (int v = 0; v < V; ++v)
make_set(subsets, v);
while(e < V - 1 && i < graph -> E)
{
Edge next_edge = graph -> edge[i++];
int x = find_set(subsets, next_edge.source);
int y = find_set(subsets, next_edge.destination);
if (x != y)
{
result[e++] = next_edge;
_union(subsets, x, y);
}
}
//return std::make_tuple(res, e);
return result_ptr;
}
void Kruskals_Algo::print_kruskals_MST(Edge* r, int e)
{
int minimumCost = 0;
for(int i=0; i<e; ++i)
{
std::cout << r[i].source << " -- "
<< r[i].destination << " == "
<< r[i].weight << std::endl;
minimumCost = minimumCost + r[i].weight;
}
std::cout << "Minimum Cost Spanning Tree: " << minimumCost << std::endl;
}
#include <iostream>
#include "Graph/Graph.hpp"
#include "Kruskals_Algo/kruskalsAlgo.hpp"
//#include "Prims_Algo/primsAlgo.hpp"
using namespace std;
class GreedyAlgos
{
public:
void kruskals_mst();
//void prims_mst();
};
void GreedyAlgos::kruskals_mst()
{
Kruskals_Algo kr;
int V;
int E;
int source, destination, weight;
cout << "\nEnter the number of vertices: ";
cin >> V;
cout << "\nEnter the number of edges: ";
cin >> E;
Edge* res;
Graph* graph = create_graph(V, E);
for(int i=0; i<E; i++)
{
cout << "\nEnter source, destinstion and weight: ";
cin >> source >> destination >> weight;
graph -> edge[i].source = source;
graph -> edge[i].destination = destination;
graph -> edge[i].weight = weight;
}
//std::tie(result, E) = kr.kruskal(graph);
res = kr.kruskal(graph);
kr.print_kruskals_MST(res, E);
}
int main()
{
int choice;
GreedyAlgos greedy;
greedy.kruskals_mst();
return 0;
}
So my question here is when I debug the program the values in Edge result[V], which is a structure array, are calculated correctly, at position [0] [1] [2] as in the following picture:
but when the function print_kruskals_MST(res, E) is called from the main the values printed are different:
Is there any pointer thing that I'm doing wrong?
Thanks in advance!
P.S. Ignore the comments!
This answer might not answer your question directly but it should shed some light on the problem.
First of all, yes you have a lot of pointer problems...
Secondly, pair ANY use of the new operator with the delete operator. As it stands, you have a bunch of memory leaks.
Also, why create_graph? Create a constructor for Graph instead (and a destructor since the class has an Edge* edge it needs to take care of).
struct Graph
{
int V;
int E;
Edge* edge;
// constructor
Graph(int V, int E)
{
this->V = V;
this->E = E;
this->edge = new Edge[E];
}
// destructor
~Graph()
{
// nullify the member variable before deleting its memory is just a safety measure pertaining to multithreading.
Edge* _edge = this->edge;
this->edge = nullptr;
delete _edge;
}
};
Then change Graph* graph = create_graph(V, E); into Graph* graph = new Graph(V, E); and do delete graph when you're done using it.
Make sure you remove all memory leaks and we can go on to discussing referencing the correct data (f.ex. by me changing my answer).

function pointer for different functions with different data types or parameter

i have this code which uses a function pointer to point 3 functions sum, subtract, mul. it works well. but now the problem is that i have functions with different no.of parameters and different data types. how to implement this.
int add(int a, int b)
{
cout<<a+b;
}
int subtract(int a, int b)
{
cout<<a-b;
}
int mul(int a, int b)
{
cout<<a*b;
}
int main()
{
int (*fun_ptr_arr[])(int, int) = {add, subtract, mul};
unsigned int ch, a = 15, b = 10,c=9;
ch=2;
if (ch > 4) return 0;
(*fun_ptr_arr[ch])(a, b);
return 0;
}
The simple answer is that technically you can't do this. You could do some manipulations using an array as input for all these functions, but you will still have to know exactly what to pass to each function. From a software engineering perspective, you should not do this - I suggest you take a look at the nice answers here: C++ Function pointers with unknown number of arguments
A slightly different approach using objects to implement the required behavior. In order to have a truly generic kind of solution, we need to use Interfaces.
Dismantle the data and operation i.e keep them separately.
//Interface which describes any kind of data.
struct IData
{
virtual ~IData()
{
}
};
//Interface which desribes any kind of operation
struct IOperation
{
//actual operation which will be performed
virtual IData* Execute(IData *_pData) = 0;
virtual ~IOperation()
{
}
};
Now, every operation knows the kind of data it work on and will expect that kind of data only.
struct Operation_Add : public IOperation
{
//data for operation addition.
struct Data : public IData
{
int a;
int b;
int result;
};
IData* Execute(IData *_pData)
{
//expected data is "Operation_Add::Data_Add"
Operation_Add::Data *pData = dynamic_cast<Operation_Add::Data*>(_pData);
if(pData == NULL)
{
return NULL;
}
pData->result = pData->a + pData->b;
return pData;
}
};
struct Operation_Avg : public IOperation
{
//data for operation average of numbers.
struct Data : public IData
{
int a[5];
int total_numbers;
float result;
};
IData* Execute(IData *_pData)
{
//expected data is "Operation_Avg::Data_Avg"
Operation_Avg::Data *pData = dynamic_cast<Operation_Avg::Data*>(_pData);
if(pData == NULL)
{
return NULL;
}
pData->result = 0.0f;
for(int i = 0; i < pData->total_numbers; ++i)
{
pData->result += pData->a[i];
}
pData->result /= pData->total_numbers;
return pData;
}
};
Here, is the operation processor, the CPU.
struct CPU
{
enum OPERATION
{
ADDITION = 0,
AVERAGE
};
Operation_Add m_stAdditionOperation;
Operation_Avg m_stAverageOperation;
map<CPU::OPERATION, IOperation*> Operation;
CPU()
{
Operation[CPU::ADDITION] = &m_stAdditionOperation;
Operation[CPU::AVERAGE] = &m_stAverageOperation;
}
};
Sample:
CPU g_oCPU;
Operation_Add::Data stAdditionData;
stAdditionData.a = 10;
stAdditionData.b = 20;
Operation_Avg::Data stAverageData;
stAverageData.total_numbers = 5;
for(int i = 0; i < stAverageData.total_numbers; ++i)
{
stAverageData.a[i] = i*10;
}
Operation_Add::Data *pResultAdd = dynamic_cast<Operation_Add::Data*>(g_oCPU.Operation[CPU::ADDITION]->Execute(&stAdditionData));
if(pResultAdd != NULL)
{
printf("add = %d\n", pResultAdd->result);
}
Operation_Avg::Data *pResultAvg = dynamic_cast<Operation_Avg::Data*>(g_oCPU.Operation[CPU::AVERAGE]->Execute(&stAverageData));
if(pResultAvg != NULL)
{
printf("avg = %f\n", pResultAvg->result);
}
If you have the following functions
int f1(int i);
int f2(int i, int j);
You can define a generic function type like this
typedef int (*generic_fp)(void);
And then initialize your function array
generic_fp func_arr[2] = {
(generic_fp) f1,
(generic_fp) f2
};
But you will have to cast the functions back
int result_f1 = ((f1) func_arr[0]) (2);
int result_f2 = ((f2) func_arr[1]) (1, 2);
Obviously, it does not look like a good way to build a program
To make code look a little bit better you can define macros
#define F1(f, p1) ((f1)(f))(p1)
#define F2(f, p1, p2) ((f2)(f))(p1, p2)
int result_f1 = F1(func_arr[0], 2);
int result_f2 = F2(func_arr[1], 1, 2);
EDIT
Forgot to mention, you also have to define a type for every type of function
typedef int (*fi)(int); // type for function of one int param
typedef int (*fii)(int, int); // type for function of two int params
And to then cast stored pointers to those types
int result_f1 = ((fi) func_arr[0]) (2);
int result_f2 = ((fii) func_arr[1]) (1, 2);
Here is a complete example
#include <iostream>
typedef int (*generic_fp)(void);
typedef int (*fi)(int); // type for function of one int param
typedef int (*fii)(int, int); // type for function of two int params
#define F1(f, p1) ((fi)(f))(p1)
#define F2(f, p1, p2) ((fii)(f))(p1, p2)
int f1(int i);
int f2(int i, int j);
int main()
{
generic_fp func_arr[2] = {
(generic_fp) f1,
(generic_fp) f2
};
int result_f1_no_macro = ((fi) func_arr[0]) (2);
int result_f2_no_macro = ((fii) func_arr[1]) (1, 2);
int result_f1_macro = F1(func_arr[0], 2);
int result_f2_macro = F2(func_arr[1], 1, 2);
std::cout << result_f1_no_macro << ", " << result_f2_no_macro << std::endl;
std::cout << result_f1_macro << ", " << result_f2_macro << std::endl;
return 0;
}
int f1(int i)
{
return i * 2;
}
int f2(int i, int j)
{
return i + j;
}
The code above produces the following output
4, 3
4, 3

Error when resizing vector of object

I am trying to create a vector of objects but i have some issues. I can't push_back over 19 objects to my vector because it shows up an error message of bad_alloc.
I try to resize my vector with resize() or reserve() but still nothing.
For resize(), I read that you need to provide 2 arguments to resize a vector.But still nothing.
When I try to use it without push_back it shows error: expected primary-expression before ')' token.
#define N 10 //ari8mos seirwn tou xarth
#define M 10 //ari8mos sthlwn tou xarth
#define TREAS 100//posothta 8usaurou
#define PORTS 100//ari8mos limaniwn
extern void ships(map (&myArray)[N][M], vector<ship> &myShips);
void ships(map (&myArray)[N][M], vector<ship> &myShips)
{
int i,j,y;
srand ( time(NULL) );
//myShips.reserve(21);
//myShips.resize(20,ship);
cout << myShips.capacity() << endl;
int x=0;
for( i = 0; i <19 ; i++){
myShips.push_back(pirate(rand() % N,rand() % M,100,100,100,1,'#',myArray,myShips));
}
for( i=0;i<myShips.size();i++ ){
cout << myShips[i].get_symbol() << " ";
}
}
here is the rest of code to help you understand:
class ship
{
protected:
int i,j,x2,y2;
//vector<vector<map> > myArray;
//ship (&myShips)[N][M];
int x;
int y;
map (myArray)[N][M];
vector<ship> myShips;
int max_resistance;
int current_resistance;
int speed;
int reserve_treasure;
char symbol;
public:
ship(int x_, int y_, int max_res, int cur_res, int res_treas, int sp, char sy, map (&myArr)[N] [M], vector<ship> &Ship)
:x(x_)
,y(y_)
,max_resistance(max_res)
,current_resistance(cur_res)
,reserve_treasure(res_treas)
,speed(sp)
,symbol(sy)
,myArray(myArr)
,myShips(Ship)
{cout << "eimai o 'ship' 2" << endl; }
~ship() {}
int get_x();
int get_y();
float get_max_resistance();
float get_current_resistance();
int get_speed();
float get_reserve_treasure();
char get_symbol();
void set_x(int pos_x);
void set_y(int pos_y);
void set_max_resistance(float maxres);
void set_current_resistance(float curres);
void set_speed(int sp);
void set_reserve_treasure(float restrea);
void set_symbol(char sy);
void movement();
void operation();
};
int ship::get_x(){
return x;
}
int ship::get_y(){
return y;
}
float ship::get_max_resistance(){
return max_resistance;
}
float ship::get_current_resistance(){
return current_resistance;
}
int ship::get_speed(){
return speed;
}
float ship::get_reserve_treasure(){
return reserve_treasure;
}
char ship::get_symbol(){
return symbol;
}
void ship::set_x(int pos_x){
x = pos_x;
}
void ship::set_y(int pos_y){
y = pos_y;
}
void ship::set_max_resistance(float maxres){
max_resistance = maxres;
}
void ship::set_speed(int sp){
speed = sp;
}
void ship::set_current_resistance(float curres){
current_resistance = curres;
}
void ship::set_reserve_treasure(float restrea){
reserve_treasure = restrea;
}
void ship::set_symbol(char sy){
symbol = sy;
}
class pirate : public ship
{
public:
pirate(int posx, int posy, float mr, float cr, float rt, int spe, char sym, map (&Array)[N] [M],vector<ship> &Ship ):ship(posx,posy,mr,cr,rt,spe,sym,Array,Ship){
cout << "eimai o 'pirate' 1" << endl;
// ship(90,90,1,50,'#',Array,Ship) {//vector<vector<map> > Array, vector<vector<ship> > Ship) {}
};
Hope you can help
Looking through this code, did you create a custom definition for map? Otherwise, if you are trying to create an [N][M] array of Map objects, you are missing the type declaration of map. e.g. map<int,string>
If you are trying to use map as a multidimensional array, this is not what std::map is for. Map is a generic container for storing key/value pairs.

C++ push_back overwrites last vector element

Since I cannot answer my own question in 8 hours after asking, I'm posting my solution here.
Made some mistakes in the incoming channel number and number of the vector element. Setting the value of channel-1 instead of channel fixed to problem.
My new function is as follows:
void input(long inlet, t_symbol *s, long ac, t_atom *av){
// GET VARIABLES
long channel = atom_getlong(av);
double value = atom_getfloat(av + 1);
long v_size = v_chan.size();
if(channel && v_size < channel){
for(int i = v_size; i < channel; i++){
v_chan.push_back(n_chan);
}
v_chan[channel - 1].value = value;
}
else if(channel){
v_chan[channel - 1].value = value;
}
}
I've got a vector containing structs, which I like to push_back with a new, empty struct.
Example code:
struct channels{
double value;
// eventually more variables
};
vector<channels> v_chan;
channels n_chan;
void push(){
v_chan.push_back(n_chan);
}
The problem is, if my vector contains elements, push_back add an element, but also overwrites the last element.
For example, if my vector size is 1 and element 0 has a value of 0.2, after push_back my vector size is 2, but element 0 and 1 have a value of 0.
What am I doing wrong here?
Real Code: (MAX/MSP external, function input is called in Max)
#include <maxcpp6.h>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
struct bind{
string param;
double* value;
int track;
double base;
double multiplier;
};
struct channels{
double value;
vector<int> bind;
};
vector<channels> v_chan;
vector<bind> v_bind(19);
channels n_chan;
class rec : public MaxCpp6<rec> {
public:
rec(t_symbol * sym, long ac, t_atom * av) {
setupIO(1, 1); // inlets / outlets
}
~rec() {}
// methods:
//SET BIND FUNCTION
void setBind(long inlet, t_symbol *s, long ac, t_atom *av){
}
void output(long track, long type){
}
void input(long inlet, t_symbol *s, long ac, t_atom *av){
// GET VARIABLES
long channel = atom_getlong(av);
double value = atom_getfloat(av + 1);
long v_size = v_chan.size();
if(v_size <= channel){
v_chan.push_back(n_chan);
}
else{
v_chan[channel].value = value;
}
}
void dump(long inlet){
for(int i = 1; i <= v_chan.size(); i++){
post("%d %.2f", i, v_chan[i].value);
}
}
void clearTrackBinds(long inlet){
}
void reset(long inlet){
clearTrackBinds(0);
}
};
C74_EXPORT int main(void) {
// create a class with the given name:
rec::makeMaxClass("solar_receiver");
REGISTER_METHOD_GIMME(rec, input);
REGISTER_METHOD_GIMME(rec, setBind);
REGISTER_METHOD(rec, dump);
REGISTER_METHOD(rec, clearTrackBinds);
REGISTER_METHOD(rec, reset);
}

unable to access function

I made a program for binary heap given below-
#include<iostream>
using namespace std;
/**
* Construct the binary heap.
* capacity is the capacity of the binary heap.
*/
class BinaryHeap
{
private:
int currentSize; // Number of elements in heap
int array[]; // The heap array
void buildHeap( );
void percolateDown( int hole );
public:
bool isEmpty( ) const;
bool isFull( ) const;
int findmini( ) const;
void insert( int x );
void deleteMin( );
void deleteMin( int minItem );
void makeEmpty( );
public :
BinaryHeap( )
{
currentSize = 0;
}
BinaryHeap( int capacity )
{
array[capacity + 1];
currentSize = 0;
}
};
int main()
{
int resp, ch, choice;
int n, i;
cout << "enter the size of heap" << endl;
cin >> n;
BinaryHeap b(int n);
cout << "enter the item " << endl;
cin >> ch;
b.insert( int ch);
return 0;
}
while compiling it gives errors
request for member 'insert' in 'b', which is of non-class type 'BinaryHeap(int)'
and
expected primary-expression before 'int'
why is this happening and how could it be resolved?
Remove int from BinaryHeap b(int n); and b.insert( int ch); and you are good to go.
When you call a function you shouldn't specify the data type of the variables you call it with.
Try changing this
b.insert( int ch);
to this:
b.insert(ch);