Modifying private class variables within a class method? - c++

This is probably a really basic error I'm making, but I'm quite new to c++ so please don't judge!
Basically, I've got two classes as follows:
class A{
private:
vector< vector<int> > images;
public:
int f1(int X, int Y);
}
class B{
private:
int x;
int y;
public:
int f2(A var);
}
I want to be able to call B.f2(A) with defined variables A and B and have f2() call A.f1(x,y). So far, all this works.
But the function f1 assigns values to the vector 'images' which aren't there when f2() returns. Any ideas why?
Here's the code:
int A::f1(int X, int Y){
// Some stuff to resize images accordingly
images[X][Y] = 4;
return 0;
}
int B::f2(A var){
var.f1(x, y);
return 0;
}
int main(){
A var1;
B var2;
// Stuff to set var2.x, var2.y
var2.f2(var1);
// HERE: var1.images IS UNCHANGED?
}

this is because you have passed A by value. instead, pass it by reference.
void fn(A& p);
^ << refer to the original object passed as the parameter.
as it is now, your program creates, and then mutates a copy of var1.
when you do not want to mutate the parameter, you can pass it as a const reference:
void fn(const A& p);
^^^^^ ^

Related

C++ What is the point of using const in a class setter function?

I am going through a text book to freshen up my (fairly bad) C++ knowledge and I came across this code example (shortened):
class MyClass{
private:
int count;
double price;
string name;
public:
void setValues(const int&, const double&, const string&);
};
void MyClass::setValues(const int& c, const double& p, const string& n){
count = c;
price = p;
name= n;
}
int main(){
myClass pOne;
pOne.setValues(5, 0.75, "Kiwi");
return 0;
}
The Way I understand the const keyword and the way it was described in the book thus far is that I can use it to declare constants, which should not be subject to change. This is better for the compiler since it knows that the values won't change.
But here I use const every time I set values
void MyClass::setValues(const int& a, const double& p, const string& b)
once the values of pOne are set, I can change them over and over with the setValues function, so what is the point of making them const?
once the values of pOne are set, I can change them over and over with the setValues function, so what is the point of making them const?
This is flawed logic. Consider this small example:
const int x = 42;
int y = x;
The value of x is assigned to y. Just because x is constant does not imply that y is too. You can change the value of y afterwards.
In the function signature the const means the usual: You cannot modify the parameters. It would be odd if a setter would change them.
struct foo {
int value = 42;
void set(int& x) {
value = x;
x = 42; // what ?!?
}
};
int main() {
int a = 2;
foo f;
f.set(x);
std::cout << x; // prints 42.... what?!?
const int b = 3;
f.set(b); // error because b is const :(
}
The setter takes its parameters by constant references because it tries to avoid a copy (hence reference) and parameters are not modified by the call (hence const).
Passing int as const int& however, is not really recommended, because it isn't cheaper than passing the int by value.

C++ "Incomplete type is not allowed" trying to create array of functions inside a class

How do I get the below code example, that compiles and works just fine to work inside a class?
Below code works just fine
#include <iostream>
using namespace std;
typedef int (*IntFunctionWithOneParameter) (int a);
int function(int a){ return a; }
int functionTimesTwo(int a){ return a*2; }
int functionDivideByTwo(int a){ return a/2; }
void main()
{
IntFunctionWithOneParameter functions[] =
{
function,
functionTimesTwo,
functionDivideByTwo
};
for(int i = 0; i < 3; ++i)
{
cout << functions[i](8) << endl;
}
}
So the above code works fine, but I want to move it inside a class in a separate file, similar to the below NON-WORKING IDEA, where I get "incomplete type is not allowed" error at "functions[] =";
class myClass {
private:
typedef int (*IntFunctionWithOneParameter) (int a);
int function(int a){ return a; }
int functionTimesTwo(int a){ return a*2; }
int functionDivideByTwo(int a){ return a/2; }
IntFunctionWithOneParameter functions[] =
{
function,
functionTimesTwo,
functionDivideByTwo
};
};
So my question is how can I get it to work inside my class, where it is the ONLY place the functions are needed, meaning I do need to access the functions in main() or other places!
EDIT
Here is why I need an "array of functions". To save time spent on "if's" or more exactly "switches" as I am making a software (vst) synthesizer, and the less time spent in the processing, the more notes (polyphonic) the user can play at any given time. And multiply the 44100 times per second the function is run, with 8 tone generators, which each can have up to 16 unison voices, so actually the function needed, may be called up to 5,644,800 times per second, per note played! The exact function needed inside this main loop is known BEFORE entering loop, and ONLY changes when the user adjust a knob, so I do want to avoid ifs and switches. Now had it only been one function that occasionally changes, i could just duplicate main loop with variations for each function possible, HOWEVER the main audio processing loop, has several areas, each with a variety of ever growing functions possible, each which ONLY changes when user changes various knobs. So although I could, I am not going to make 5 * 20 * 23 (and growing) different versions of a main loop, to avoid if's and switches.
There's a bunch of things wrong with the code that you posted:
No semicolon after class definition.
Class instead of class
No fixed size set for the functions member, which is not allowed. You need to explicitly set the size of the array.
Member function pointers are not the same as "regular" function pointers. Member function pointers have an implicit this as first argument, since they need an object to be invoked on. So myFunction is not of type myArrayOfFunctions. If you make myFunction and myFunction2 static, then they can be stored as regular function pointers. Is this an option?
The name myArrayOfFunctions is very confusing, since it's not an array at all.
All but the last of these will cause your code not to compile.
This example may be what you've needed.
Note: I've changed typedef statement to using and changed function's signatures to take in plain int for testing convinience sake.
class myClass {
public:
using myArrayOfFunctions = float(myClass::*)(int a, int b, float c);
float myFunction1 (int a, int b, float c)
{
return a * b * c;
}
float myFunction2 (int a, int b, float c)
{
return a + b + c;
}
myArrayOfFunctions functions[2];
myClass()
{
functions[0] = &myClass::myFunction1;
functions[1] = &myClass::myFunction2;
};
void Invoke()
{
(this->*functions[0])(1, 2, 3);
(this->*functions[1])(3, 2, 1);
}
};
int main()
{
myClass a;
a.Invoke();
(a.*(a.functions[0]))(4, 5, 6);
return 0;
}
As you see, I'm getting the pointer to the class function but to call it I need to call it with an actual object (this in invoke() function and a object in main()).
You can write this:
class myClass
{
public:
typedef float (*myArrayOfStaticFunctions) (int& a, int& b, float& c);
typedef float (myClass::*myArrayOfFunctions) (int& a, int& b, float& c);
static float myFunction1 (int& a, int& b, float& c){cout<<"myFunction1"<<endl; return 0;}
static float myFunction2 (int& a, int& b, float& c){ cout<<"myFunction2"<<endl; return 0;}
float myFunction3 (int& a, int& b, float& c){ cout<<"myFunction3"<<endl; return 0;}
float myFunction4 (int& a, int& b, float& c){ cout<<"myFunction4"<<endl; return 0;}
myArrayOfStaticFunctions StaticArrayfunctions[2];
myArrayOfFunctions Arrayfunctions[2];
myClass (){
StaticArrayfunctions [0] =myFunction1;
StaticArrayfunctions [1] =myFunction2;
Arrayfunctions [0] = &myClass::myFunction3;
Arrayfunctions [1] = &myClass::myFunction4;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
myClass m;
int a =0, b=0; float c;
m.StaticArrayfunctions[0] (a,b,c);
m.StaticArrayfunctions[1] (a,b,c);
myClass::myArrayOfFunctions func3 = m.Arrayfunctions[0];
myClass::myArrayOfFunctions func4 = m.Arrayfunctions[1];
(m.*func3)(a,b,c);
(m.*func4)(a,b,c);
return 0;
}

How to chain multiple operator[]

I am trying to create a class that use the operator [] like
MyClass[x][y]
and it should return a value based on what I call in the function that is defined within the class. What I have so far is:
MyClass.h
class MyClass{
public:
// return one value of the matrix
friend double operator[][] (const int x, const int y);
}
I don't even think my syntax for this is right, and how can I write this function in MyClass.cpp to define what value it should return?
Like is it:
MyClass::friend double operator[][] (const int x, const int y)
{
// insert code here
}
Tried it but it keeps saying errors. I believe it is a mess up there...
Many thanks,
Overloading operator() is definitely the cleanest approach.
However, remember that this is C++, and you can bend the syntax to your will :)
In particular, if you insist on wanting to use myclass[][], you can do so by declaring an "intermediate class", here's an example:
Run It Online
#include <iostream>
using std::cout;
using std::endl;
class MyClass {
public:
using IndexType = int;
using ReturnType = double;
// intermediate structure
struct YClass {
MyClass& myclass;
IndexType x;
YClass (MyClass& c, IndexType x_) : myclass(c), x(x_) {}
ReturnType operator[](IndexType y_) { return myclass.compute(x, y_); }
};
// return an intermediate structure on which you can use opearator[]
YClass operator[](IndexType x) { return {*this, x}; }
// actual computation, called by the last "intremediate" class
ReturnType compute(IndexType x, IndexType y) {
return x * y;
}
};
int main()
{
MyClass myclass;
cout << myclass[2][3] << endl; // same as: cout << myclass.compute(2, 3) << endl;
}
You need to return a proxy object for the row. This is a very simplified example just to get you going. I have not tried compiling it.
class Matrix {
int data[4][4];
class Row {
Matrix* matrix;
int row;
int operator[](int index){
return matrix->data[row][index]; // Probably you want to check the index is in range here.
}
}
Row operator[](int row){
Row which_row;
which_row.matrix = this;
which_row.row = row; // beware that if the user passes the row around it might point to invalid memory if Matrix is deleted.
return which_row;
}
}
You could also just return the row directly from operator[] and leave the second [] to be a direct array access. IMHO it is nice with the proxy object as it can do some checking on the index and possibly have other nice member functions.
There is no operator[][]. But you can declare operator()(int, int) instead.
class Foo {
public:
double operator()(int a, int b) {
//...
}
};
If you're trying to create 4x4 Matrix class, the way I did it and the way its done in the D3DX library is to have a member variable in the class:
class Matrix
{
public:
// publicly accessible member 4x4 array
float m[4][4];
// also accessible via () operator. E.G. float value = mtx(3,2);
float operator()(int column, int row);
}

how to return multiple values from get function in c++ [duplicate]

This question already has answers here:
Returning multiple values from a C++ function
(23 answers)
Closed 8 years ago.
I am basically passing two parameters in the private class and I am trying to access these two parameters in my main function. Since I made those two parameters private, I am using get and set functions to access these parameters, but I am not able to return two values from the get function. Please help me. The last post that asked kind of same question, but this time it has been asked for object oriented concept.
class FirstClass{
public:
void setName(int x,int y){
a = x;
b = y;
}
int getName(){
return a,b;
}
private:
int a,b;
};
Either use references:
int getName(int &a1, int &b1) {
a1 = a;
b1 = b;
}
or use two functions:
int getA() {
return a;
}
int getB() {
return b;
}
You can return a single value or take parameters as value-result arguments ( pointers or references) or return structure with parameters packed. Most probably you will need to access just a or just b separately after all, so why not to just create two accessors
int getNameA(){
return a;
}
int getNameB(){
return b;
}
accessors/mutators or getters/setters are intended to get/set only one value. Your code should be like this:
class FirstClass{
public:
FirstClass(int x,int y){ //constructor, initialize the values
a = x;
b = y;
}
int getA(){
return a;
}
int getB(){
return b;
}
int setA(const int newVal){ //using const is a good practice
a=newVal;
}
int setB(const int newVal){ //using const is a good practice
b= newVal;
}
// you can use reference/pointer to *obtain* multiple values, although it is rarely used and seems inappropriate in your code
void getBoth(int& aRef, int& bRef){
aRef = a;
bRef = b;
}
private:
int a,b;
};

Multidimensional array assignment

if you look at this class, how do I achieve the following:
class foo {
public:
void foo(double (&arr)[3][4]) { //Constructor
arr2 = arr; //??? How to assign multidimensional arrays?
}
void bar() { //Usage
double doSomething = arr2[1][0];
}
private:
double* arr2[3][4]; //??? How to store this?
}
Thanks everyone!
More explanation: This should be a class, that get a reference to a two-dimensional array in its constructor (foo()). It stores this reference in a member variable, so that some other function (bar()) can access them later.
So what "format" has the member variable and how do I assign the parameter of the constructor to it?
Edit2: As I impement an interface, I can't change signatures to use std::vector>...
class foo {
public:
// See http://cdecl.ridiculousfish.com/?q=double+%28%26arr%29%5B3%5D%5B4%5D
foo(double (&arr)[3][4]) :arr2(&arr) {
// This constructor uses constructor list initialization, but you could have used
// assignment instead, like this:
// arr2 = &arr;
}
double bar() { //Usage
double doSomething = (*arr2)[1][0];
return doSomething*doSomething;
}
private:
// See http://cdecl.ridiculousfish.com/?q=double+%28*arr2%29%5B3%5D%5B4%5D
double (*arr2)[3][4];
};
int main () {
double oof[3][4] = {{0.,},};
foo moo(oof);
return int(moo.bar());
}
Since you don't specify a reason for using raw pointers and this is tagged C++, you should use nested vectors instead:
#include <vector>
class foo
{
public:
void foo(const std::vector<std::vector<double>>& arr)
: arr2(arr)
{ //Constructor
}
void bar() { //Usage
double doSomething = arr2[1][0];
}
private:
std::vector<std::vector<double>> arr2;
};