My question is how to access and modify a 2D array defined in one class that is friends with another class. Below are some details on my question:
In class A I declare and allocate the appropriate space for my 2D array (pointer-to-pointer) u.
Class A
{
public:
friend class B;
long double **u;
int fun;
void make();
};
void A::make()
{
long double **u = new long double *[nx];
for (int i=0;i<nx;i++)
u[i] = new long double [ny];
int fun = 9;
}
Class A is friends with Class B; I need to use the array I declared in Class A in a function defined in class B. Below is my Class B:
class B
{
public:
void get(A*);
};
void B::get(A *pt)
{
using namespace std;
cout << pt->fun;
cout << pt->u[0][0];
}
I get a Bus error on my second cout pt->u[0][0]. Is there a simple way to use this setup I have to access my u[][] array? I think that I get the error because the pointer points to the 1st entry of my array, thus my whole 2D array is saved in memory as a single row (thinking aloud here). I'm a Fortran guy so this stuff is a little new to me.
Any help or "pointers" to other helpful threads would be appreciated.
Thank you !
Alberto
I think you get error because A::u is not initialized ( in method A::make you initialize a local variable u, not member. You need to change
void A::make()
{
long double **u = new long double *[nx]; // should be just u, or this->u.
There are some problems with your code: nx and ny don't seem to be defined anywhere, and in make you don't initialize A::fun at all, you instead set a local variable named fun which goes out of scope immediately.
As for your error, it sounds like the error stems from the fact that make() has not been called on pt. Ensure that make() is called on the instance you pass to get, otherwise the array u will not be allocated.
Related
I am a newbie in C++. Here in my case I have created two classes, class One and class Two. _x is declared as a private member variable of class One. So here I am trying to learn different methods to access this private variable(_x) from any other class(Here in this case it is class Two). This is my scenario basically. So one method I tried is ,making class Two as a friend class of class One and for accessing this variable, I have used directValOfOne function to print the value of this variable and another one I tried was passing the address of the class One instance in another member function (getDataTwo) of class Two. Everything works well until here.
As you can see, I have initialized the _x using a parameterized constructor and printing this variable gives me the value as 10 using both the methods. Again I modified this variable using a
setter function (setDataOne) to 220 and when I print it using the getDataTwo function it prints the value as 220. But when I tried to print the value using directValOfOne, it still showing the old initialized value (10) which I am really confused. I have printed the address of class One object in this directValOfOne funtion and it shows same. If so then why the new value(220) is not updated here.
Source code is placed below.
#include <iostream>
using namespace std;
class One{
int _x;
public:
One(int a):_x{a} {}
//setters and getters
void setDataOne(int a) { _x = a; }
int getDataOne() const { return _x; }
//print values
void printOne() { cout<<"_x - "<<_x<<endl; }
friend class Two;
};
class Two{
One _a;
int id_one = 0;
public:
Two(One a):_a{a} {}
//setters and getters
void setDataTwo(int a) { }
int getDataTwo(One *obj) {
id_one = obj->getDataOne();
return id_one;
}
void printTwo() { printf("id_one = %d\n",id_one); }
void directValOfOne() {
printf("address = %p\n",&_a);
printf("_a._x = %d\n",_a._x);
}
};
int main(){
One one(10);
Two two(one);
one.printOne();
two.getDataTwo(&one);
two.printTwo();
two.directValOfOne();
printf(" *********** \n");
one.setDataOne(222);
one.printOne();
two.getDataTwo(&one);
two.printTwo();
two.directValOfOne();
return 0;
}
and the console output is,
_x - 10
id_one = 10
address = 006dfee4
_a._x = 10
***********
_x - 222
id_one = 222
address = 006dfee4
_a._x = 10
As you can see the _a._x still prints the value 10. But actually the _x is updated to new value 220. Sorry if I explained it so detail. Just to give you an overview I detailed like this.
So my que is ,
Why it is not showing the updated value since the addresses are same?
Am I missing any important concept here ? If so please guide me to understand this problem.
The problem in your code is that you pass to Two an instance of class One by value. This means that Two stores a copy of the instance of One you pass to it. When you change the value of _x in one it does not affect the value of _x in _a (inside two).
In order for your code to work you need to pass a reference to One in Two's constructor and store this reference. Now every change to one will also affect _a.
Modified code:
class Two{
One& _a;
int id_one = 0;
public:
Two(One& a):_a(a) {}
// ...
Regarding the address issue, the address of _a will stay the same since there's no reason for it to change once initialized. If you'll print the address of one in your current code (before the suggested modifications) it should be in a different address than _a (since _a is a copy that's located somewhere else).
In the modified version of the code you should see the same address since it's the same object.
I wanted to practice building classes. I learned in my class that having leaked memory is never good, When I call this class, am I creating an object and do I need to add a delete function in my destructor to avoid leaks? Thank you!!!
#include <iostream>
#include <string>
using namespace std;
class Quadratic
{
public:
Quadratic(int ia, int ib, int ic);
int evaluate(int x);
private:
int a, b, c;
};
Quadratic::Quadratic(int ia, int ib, int ic)
{
a = ia;
b = ib;
c = ic;
}
int Quadratic::evaluate(int x)
{
int answer = a * (x * x) + b * x + c;
return answer;
}
Quadratic::~Quadratic() // ctrl + k + c to comment out large section of code.
{
cout << "Goodbye" << endl;
}
void main()
{
int list[3] = { 2,3,4 };
int* p1 = &list[0];
int* p2 = &list[1];
int* p3 = &list[2];
// calling a class looks like this
Quadratic* problem = new Quadratic(2, 3, 4);
int answer = problem->evaluate(0);
cout << answer << endl;
}
I can see three problems with your code, first of all the destructor: In the destructor you should free any dynamic items created in this case you have none which is good, also you should set your variables to their default value. Reset values for a, b, and c. Secondly the call problem->evaluate shouldn't work. I would not declare Quadratic* name, just do Quadratic name. Replace problem->evalute with problem.evalute. Finally it is usually an industry convention to seperate your header and implementation files with the exception of templates.
C++ does not provide garbage collection, so yes, you do need to delete memory manually.
You can do this by typing
delete problem;
after you are done using it.
You need to add destructor to your class functions:
~Quadratic();
Additionally, you need to add
delete problem;
to your main function for relase the occupied memory by your pointer.
For those of you who are saying delete problem..... That is exactly why you do not create a pointer for Quadratic..... Get rid of the * symbol after Quadratic and you do not need to delete it later. Generally we don't use * symbol after object, there are exceptions through.... Been coding in c++ for 3 years now and I rarely see people use the * after the object in a program this size..... * means dynamic memory allocation.... Which you probably do not want to do...
thanks,
Yun Fei Chen
I am trying to access the variable i declare in my nested class, but i fail to get the answer i want at the console. The result i want is 100, but all that i get is a long number. I cannot seem to find the error. This is what i wrote:
#include <iostream>
using namespace std;
class shpia {
public:
int tot;
class dhoma1 {
public:
int gjatesi;
int di() {
return gjatesi * gjatesi;
}
};
dhoma1 dh1;
void redi(){
cout<<dh1.di();
}
};
int main()
{
shpia::dhoma1 k;
k.gjatesi = 10;
shpia r;
r.redi();
return 0;
}
There's nothing surprising about your result. You seem to think
shpia::dhoma1 k;
k.gjatesi=10;
will define a dhoma1 for all shpia objects you will create. This is wrong. You just defined a shpia::dhoma1 object that has nothing to do with shpia objects.
When you then define
shpia r;
this will create in r another dhoma1, unrelated to the first one, which is not initialized. Hence when you print the square you're getting non-sense.
You are accessing uninitialized memory.
Here you create an instance of the nested class, and initialize its member:
shpia::dhoma1 k;
k.gjatesi=10;
And here you create an instance of the main class, which has nothing to do with the k. It already has a nested class member variable defined itself (r.dh1)
shpia r;
r.redi();
return 0;
Because of this new declaration, the nested class of r has no defined value and when you call redi(), you will access undefined memory and therefore get some random number. Depending on the actual runtime layout of your application, this value can change. It is undefined and you have to define it before you use it.
To fix this, you should use the nested class member of the main class instead, like this:
shpia r;
r.dh1.gjatesi = 10;
r.redi();
return 0;
For example:
const int m = 10;
class C{
public:
double A[m];
};
int main(){
C name;
name.A[m] = ... // initializing here?
}
I can't find a way around that, I could for example do
C name = {...};
Which would perfectly work but for the sake of functionality I wanna know if I can do that for single variables inside the class.
In your example, you only need to write:
name.A[x]=value;
Where value is double and x is between 0 and 9. You can also make a loop if you wish to set values for all or some of its elements.
I'm having this problem for quite a long time - I have fixed sized 2D array as a class member.
class myClass
{
public:
void getpointeM(...??????...);
double * retpointM();
private:
double M[3][3];
};
int main()
{
myClass moo;
double *A[3][3];
moo.getpointM( A ); ???
A = moo.retpointM(); ???
}
I'd like to pass pointer to M matrix outside. It's probably very simple, but I just can't find the proper combination of & and * etc.
Thanks for help.
double *A[3][3]; is a 2-dimensional array of double *s. You want double (*A)[3][3];
.
Then, note that A and *A and **A all have the same address, just different types.
Making a typedef can simplify things:
typedef double d3x3[3][3];
This being C++, you should pass the variable by reference, not pointer:
void getpointeM( d3x3 &matrix );
Now you don't need to use parens in type names, and the compiler makes sure you're passing an array of the correct size.
Your intent is not clear. What is getpointeM supposed to do? Return a pointer to the internal matrix (through the parameter), or return a copy of the matrix?
To return a pointer, you can do this
// Pointer-based version
...
void getpointeM(double (**p)[3][3]) { *p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(&A);
}
// Reference-based version
...
void getpointeM(double (*&p)[3][3]) { p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(A);
}
For retpointM the declaration would look as follows
...
double (*retpointM())[3][3] { return &M; }
...
int main() {
double (*A)[3][3];
A = moo.retpointM();
}
This is rather difficult to read though. You can make it look a lot clearer if you use a typedef-name for your array type
typedef double M3x3[3][3];
In that case the above examples will transform into
// Pointer-based version
...
void getpointeM(M3x3 **p) { *p = &M; }
...
int main() {
M3x3 *A;
moo.getpointM(&A);
}
// Reference-based version
...
void getpointeM(M3x3 *&p) { p = &M; }
...
int main() {
double (*A)[3][3];
moo.getpointM(A);
}
// retpointM
...
M3x3 *retpointM() { return &M; }
...
int main() {
M3x3 *A;
A = moo.retpointM();
}
The short answer is that you can get a double * to the start of the array:
public:
double * getMatrix() { return &M[0][0]; }
Outside the class, though, you can't really trivially turn the double * into another 2D array directly, at least not in a pattern that I've seen used.
You could create a 2D array in main, though (double A[3][3]) and pass that in to a getPoint method, which could copy the values into the passed-in array. That would give you a copy, which might be what you want (instead of the original, modifiable, data). Downside is that you have to copy it, of course.
class myClass
{
public:
void getpointeM(double *A[3][3])
{
//Initialize array here
}
private:
double M[3][3];
};
int main()
{
myClass moo;
double *A[3][3];
moo.getpointM( A );
}
You may want to take the code in your main function which works with the 2D array of doubles, and move that into myClass as a member function. Not only would you not have to deal with the difficulty of passing a pointer for that 2D array, but code external to your class would no longer need to know the details of how your class implements A, since they would now be calling a function in myClass and letting that do the work. If, say, you later decided to allow variable dimensions of A and chose to replace the array with a vector of vectors, you wouldn't need to rewrite any calling code in order for it to work.
In your main() function:
double *A[3][3];
creates a 3x3 array of double* (or pointers to doubles). In other words, 9 x 32-bit contiguous words of memory to store 9 memory pointers.
There's no need to make a copy of this array in main() unless the class is going to be destroyed, and you still want to access this information. Instead, you can simply return a pointer to the start of this member array.
If you only want to return a pointer to an internal class member, you only really need a single pointer value in main():
double *A;
But, if you're passing this pointer to a function and you need the function to update its value, you need a double pointer (which will allow the function to return the real pointer value back to the caller:
double **A;
And inside getpointM() you can simply point A to the internal member (M):
getpointeM(double** A)
{
// Updated types to make the assignment compatible
// This code will make the return argument (A) point to the
// memory location (&) of the start of the 2-dimensional array
// (M[0][0]).
*A = &(M[0][0]);
}
Make M public instead of private. Since you want to allow access to M through a pointer, M is not encapsulated anyway.
struct myClass {
myClass() {
std::fill_n(&M[0][0], sizeof M / sizeof M[0][0], 0.0);
}
double M[3][3];
};
int main() {
myClass moo;
double (*A)[3] = moo.M;
double (&R)[3][3] = moo.M;
for (int r = 0; r != 3; ++r) {
for (int c = 0; c != 3; ++c) {
cout << A[r][c] << R[r][c] << ' ';
// notice A[r][c] and R[r][c] are the exact same object
// I'm using both to show you can use A and R identically
}
}
return 0;
}
I would, in general, prefer R over A because the all of the lengths are fixed (A could potentially point to a double[10][3] if that was a requirement) and the reference will usually lead to clearer code.