Classes and objects: Variables

From what I have understood declaring variables as public in a class is generally not good programming practice. Would anyone like to comment on the code below whether it is done properly?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 #include <iostream>
using namespace std;

class Regner{
public:
	void Udregn(double x, double y){
		z=x;
		w=y;
		cout<<"Indtast en x værdi: ";
		cin>>z;
		cout<<"Indtast en y værdi: ";
		cin>>w;

		cout<<"x + y = "<<z+w<<endl;
		cout<<"x - y = "<<z-w<<endl;
		cout<<"x * y = "<<z*w<<endl;
	}
private:
	double z,w;
};

int main(){

	double x=0,y=0;

	Regner find;
	find.Udregn(x,y);

	return 0;
}
To me that looks like a way of just calling a function, which might be done better like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;

void find()
{
    double x, y;
    
    cout << "Enter x: ";
    cin >> x;
    cout << "Enter y: ";
    cin >> y;

    cout << "x + y = " << x + y << endl;
    cout << "x - y = " << x - y << endl;
    cout << "x * y = " << x * y << endl;    
}

int main()
{
    find();
}



If you wanted to make use of a class, I'd suggest perhaps something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
using namespace std;

class Regner {
public:
    Regner() : x(0), y(0) { }                   // constructor
    Regner(double a, double b) : x(a), y(b) { } // constructor
    
    void getInput()
    {
        cout << "Enter x: ";
        cin >> x;
        cout << "Enter y: ";
        cin >> y;        
    }
    
    void calculate()
    {
        cout << "x + y = " << x + y << endl;
        cout << "x - y = " << x - y << endl;
        cout << "x * y = " << x * y << endl;           
    }   
    
private:
    double x;
    double y;
};

int main()
{
    Regner test(3, 7);    // construct an object
    test.calculate();     // use it

    Regner find;          // construct a default object
    find.getInput();      // ask for user input
    find.calculate();     // use it
}


Thaks for the reply. but could you explain what is going on with the constructors here

1
2
Regner() : x(0), y(0) { }                   // constructor
    Regner(double a, double b) : x(a), y(b) { } // constructor 


This is an initialiser-list syntax.
 
Regner(double a, double b) : x(a), y(b) { }
It is similar to
1
2
3
4
5
Regner(double a, double b) 
{
    x = a;
    y = b;
}


The end result is the same, but the first way is the preferred method. This Regner(double a, double b) : x(a), y(b) { } directly creates the variable with the specified value.

The second way first creates the variables with the default value, and then assigns the required value as a separate step. Here it may not matter much, but it is good practice to do things the first way, with other more complex classes it can avoid unnecessary processing.


http://en.cppreference.com/w/cpp/language/initializer_list
Last edited on
So is all that
 
Regner() : x(0), y(0) { }


does is just to initialize the variables x and y?
Yes. That's the purpose of a constructor.

See the tutorial pages:
http://www.cplusplus.com/doc/tutorial/classes/
Is there ever a time when it is okay to make variables public in a class. Fx if I want to make use of an array in different classes or variables (using them as global variables) how do I go about doing this?
It depends.

You are free to make variables in a class public if it suits your purpose.
An example might be class to represent a 2D x-y coordinate, where the x and y variables might be public.

Typically in the design of a class one would make the member variables private, and allow limited access. Take for example a standard C++ string, it contains some sort of array of characters, as well as a variable representing its size. But rather than allowing direct access, there are various capabilities in order to access these values. The advantage of such tight control is that the string is always valid, the size will always accurately reflect the length of the string, and if there are internal pointers to some external character array(s), we don't get a chance to corrupt or misuse those pointers, we just get access to the things we need, while the class retains control over the things it needs.

if I want to make use of an array in different classes or variables (using them as global variables) how do I go about doing this?

I'm not sure. It's hard to speak in general terms. If you have a more concrete example of a real problem which you need to solve, then it is easier to suggest some possible solutions.
Last edited on
So I have the following unfinished flow chart which gets a matrix A and vector b (either from typing in or from a file) and then with the option of several methods finds the solution x to Ax=b

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#include <iostream>
#include <math.h>
#include <fstream>
#include <algorithm>
#define Nmax 10
using namespace std;

void test(char Valgabc,char ValgGemB,char ValgGemC, char Valg1eller23, char Valg2eller3);

class A{
public:
	A(){
		n=0;
		m=0;
	}
	void Indlaes();
private:
	double A[Nmax][Nmax],b[Nmax];
	int n,m;
};

class B{
public:
	void Indtast_b();
	void Overfoer_b();
	
private:
	double A[Nmax][Nmax],b[Nmax];
	int n,m;
};

class C{
public:
	void Indlaes_C();
	void Indtast_C1();
	void Indtast_C2();
	void Overfoer_C();
	void Projektion_b();

private:
	double A84[Nmax][Nmax],Q[Nmax][Nmax],R[Nmax][Nmax],A[Nmax][Nmax],b[Nmax];
	int n,m;
};

class Metode1{
public:
	
	void Metode1_MatrixProd();
	void Metode1_MatrixVekProd();
	void Metode1_DanTotalMatrix();
	void Metode1_Gauss();
	void Metode1_Backwardsubstitution();
	void Metode1_UdskrivVektor();
	void Kontrol_Metode1();
private:
	double A[Nmax][Nmax],M[Nmax][Nmax],AT[Nmax][Nmax],b[Nmax],W[Nmax],TM[Nmax][Nmax],FM[Nmax][Nmax],sum,x[Nmax],v[Nmax],bpNy[Nmax];
    int n,m;
};


int main(){

	char Valgabc,ValgGemB,ValgGemC,ValgProj,Valg1eller23,Valg2eller3,ValgIgen;
	
	A objectA;
	B objectB;
	C objectC;
	Metode1 object1;
	
	do{
	cout<<"Vælg a,b eller c: "<<endl;
	cin>>Valgabc;

	if(Valgabc=='a'){
	cout<<"Du indtastede: a - dermed valgte du a): Indlæs: n, m, A og b fra datafil."<<endl;
	objectA.Indlaes();
	}
	else if(Valgabc=='b'){
		cout<<"Du indtastede: b - dermed valgte du b): Indtast: n, m, A og b."<<endl;
		objectB.Indtast_b();
	cout<<"Vil du gemme n, m, A og b?"<<endl;
	cin>>ValgGemB;
	if(ValgGemB=='j'){
		cout<<"Her udskrives n, m, A og b til en datafil"<<endl;
		objectB.Overfoer_b();
	}
	}
	else if(Valgabc=='c'){
	cout<<"Du indtastede: c - dermed valgte du c): Indlæs: A_8 far datafil. Vælg n = 4 eller 8."<<endl;

	objectC.Indlaes_C();

	cout<<"Her indtastes m(<n) og R. Efterfølgende dannes Q og A = QR beregnes."<<endl;

	objectC.Indtast_C1();

	cout<<"Her indtastes x' og t'. Efterfølgende dannes bp og e og b = bp + e"<<endl;

    objectC.Indtast_C2();

	cout<<"Vil du gemme n, m, A og b?"<<endl;
	cin>>ValgGemC;
	if(ValgGemC=='j'){

    objectC.Overfoer_C();
	}
	cout<<"Der gælder at e er projektionen af b på Null{A^T}. Vil du tjekke om projektionen giver e? "<<endl;
	cin>>ValgProj;
	if(ValgProj=='j'){
		objectC.Projektion_b();
	}
	}

	cout<<"Vælg 1: 1 eller 2: 2,3"<<endl;
    cin>>Valg1eller23;
    cout<<Valg1eller23<<endl;

	if(Valg1eller23=='1'){

    object1.Metode1_MatrixProd();
    object1.Metode1_MatrixVekProd();
    object1.Metode1_DanTotalMatrix();
    object1.Metode1_Gauss();
    
	}

	else if(Valg1eller23=='2'){
		cout<<"Her udføres QR-faktorisering af A ved Gram-Schmidt faktorisering."<<endl;
		cout<<"Vælg 2 eller 3"<<endl;
		cin>>Valg2eller3;

		if(Valg2eller3=='2'){


			cout<<"Her løses Rx = Q^Tb"<<endl;
		}
		else if(Valg2eller3=='3'){
		cout<<" Her minimeres f(x)"<<endl;
		cout<<"Her skal der foretages en analyse af minimeringen. Invers Hesse-matrix og antal iterationer."<<endl;
		}
	}
	cout<<"Vil du prøve igen?"<<endl;
	cin>>ValgIgen;
	}while(ValgIgen=='j');

	cout<<"Slut"<<endl;

	cout<<"Test: Længst til venstre: "<<endl;
	test('a',ValgGemB,ValgGemC,'1',Valg2eller3);
    cout<<endl;
    cout<<"Test: Længst til højre: "<<endl;
    test('c',ValgGemB,'j','2','2');
	return 0;
}

void test(char Valgabc,char ValgGemB,char ValgGemC, char Valg1eller23, char Valg2eller3){
	cout<<"Vælg a,b eller c: "<<endl;

	if(Valgabc=='a'){
	cout<<"Du indtastede: a - dermed valgte du a): Indlæs: n, m, A og b fra datafil."<<endl;
	}
	else if(Valgabc=='b'){
		cout<<"Du indtastede: b - dermed valgte du b): Indtast: n, m, A og b."<<endl;
	cout<<"Vil du gemme n, m, A og b?"<<endl;

	if(ValgGemB=='j'){
		cout<<"Her udskrives n, m, A og b til en datafil"<<endl;
	}
	}
	else if(Valgabc=='c'){
		cout<<"Du indtastede: a - dermed valgte du a): Indlæs: A_8 far datafil. Vælg n = 4 eller 8."<<endl;
	cout<<"Her indtastes m(<n) og R. Efterfølgende dannes Q og A = QR beregnes.";
	cout<<"Her indtastes x' og t'. Efterfølgende dannes bp og e og b = bp + e"<<endl;

	cout<<"Vil du gemme n, m, A og b?"<<endl;
	if(ValgGemC=='j'){
		cout<<"Her udskrives n, m, A og b til en datafil"<<endl;
	}
	}

	cout<<"Vælg 1: 1 eller 2: 2,3"<<endl;


	if(Valg1eller23=='1'){

			cout<<"Her løses A^TAx = A^Tb"<<endl;
		}

		else if(Valg1eller23=='2'){
			cout<<"Her udføres QR-faktorisering af A ved GRam-Schmidt faktorisering."<<endl;
			cout<<"Vælg 2 eller 3"<<endl;

			if(Valg2eller3=='2'){


				cout<<"Her løses Rx = Q^Tb"<<endl;
			}
			else if(Valg2eller3=='3'){
			cout<<" Her minimeres f(x)"<<endl;
			cout<<"Her skal der foretages en analyse af minimeringen. Invers Hesse-matrix og antal iterationer."<<endl;
			}
		}
}



}


Here I'm using same arrays and variables in different functions in different classes which wasn't a problem when I just used functions. I also need the value of the number of rows n of the matrix and the number of columns m which before when I just used functions I would type in int &n and int &m in the parenthesis of the function where I would get them from. How do I go about doing all this with classes?
Not sure I can help with that. I'd need to study the algorithm which it is supposed to be performing, as well as catching up with my Danish language lessons.

Maybe someone else might like to offer some suggestions.
Topic archived. No new replies allowed.