Reputation: 53
Here is my code to define a class and input some doubles so that the member function can give a Mat object.
#include <opencv2/core.hpp>
#include <iostream>
using namespace std;
using namespace cv;
class A{
public:
void fun(double, double, double);
void printfun();
private:
Mat R;
};
int main(int argc, char* argv[]){
A a;
a.fun(0.05, 0.05, 0.5);
a.printfun();
return 0;
}
void A::fun(double R_x, double R_y, double R_theta){
R = (Mat_<double>(3,3) << R_x,0,0,0,R_y,0,0,R_theta);
#double R_init[3][3]={{R_x, 0, 0},
# {0, R_y, 0},
# {0, 0, R_theta*3.1415/180}};
#
#R = Mat(3, 3, CV_64F, R_init);
cout << R << endl;
}
void A::printfun(){
cout << R << endl;
}
In the function A::fun
, I need to compute a Mat
object R which is defined as a private variable. However, when I use the first sentence in fun to do that, both the cout
in fun()
and printfun()
give the right matrix. If I use the method in gray, the cout
in fun()
prints right but the cout
in printfun()
gives a wrong matrix R.
That is kind of weird because it seems when the fun()
returns, matrix R computed by the second method changes somehow. If this method is not used in class type, it functions right and gives a correct matrix R.
The other question is nothing related to this problem. If I could always defines a variable(say, R) in public or in private and then use a member function to assign a value to this variable, then the return type of member function could always be "void" rather than the type of the variable it assigns. Is this the way the c++ class type functions?
I am new to c++ so any help would be appreciated.
Upvotes: 0
Views: 1312
Reputation: 16816
There is a simple explanation for the behavior you are observing.
it seems when the fun() returns, matrix R computed by the second method changes somehow
Your observation is correct. Following is the difference between the first and second assignment:
In the first method, the memory for the contents of R
is allocated dynamically and then initialized with the specified values. When the function fun
returns, the contents of R
are preserved due to dynamic allocation.
In the second method, a static array R_init
(which is local to the function fun
) is initialized with the specified values. Then in the next line, R
is created and set to use the contents of R_init
. The key difference here is that no dynamic memory allocation happens. R
just uses the already allocated array R_init
for storing the values. It means if we modify R_init
, the contents of R
will also change. When fun
returns, there is no guarantee of validity of contents of R_init
(a.k.a undefined behavior) which is resulting in garbage values being printed.
Although for static initialization, the first approach is preferred. But if you really want to use the second method, you can force a separate copy of the memory using the Mat::clone
function like this:
R = Mat(3, 3, CV_64F, R_init).clone();
For the second question:
Is this the way the c++ class type functions?
The function return type may not necessarily be void
as it may be dependent on what kind of design patterns you are following. It can totally be a matter of choice.
Upvotes: 2