You are not logged in.
So I'm using OpenCV, and want to use the cv::Mat class. However I need to add some additional data points to the class. My (simple) idea was simply to create a new class, asMat, which inherits publicly from cv::Mat.
class asMat : public cv::Mat {
public:
int my_variable;
};
It 'works' in a sense, I can create a cv::Mat, static cast it to asMat, and use it in a few opencv functions, while also saving values into my_instant_name.my_variable.
However, I can't do the following:-
asMat inLeft(height,width,CV_8UC1);
Basically, I'm trying to call a particular constructor from cv::Mat. My understanding is that if I publicly inherit from cv::Mat I would also inherit all its functions. Do constructors work differently somehow (have to be explicitly specified)?
Last edited by ngoonee (2010-04-26 10:27:52)
Allan-Volunteer on the (topic being discussed) mailn lists. You never get the people who matters attention on the forums.
jasonwryan-Installing Arch is a measure of your literacy. Maintaining Arch is a measure of your diligence. Contributing to Arch is a measure of your competence.
Griemak-Bleeding edge, not bleeding flat. Edge denotes falls will occur from time to time. Bring your own parachute.
Offline
A quick google gives you tons of results on that..
Anyways, constructors are not inherited. What you need to do is:
class asMat ....
{
....
public asMat(...) : cv::Mat(...)
...
}
Edit:
StackOverflow usually has good answers: http://stackoverflow.com/questions/3473 … nstructors
Last edited by schuay (2010-04-23 11:31:01)
Offline
If cv::Mat's constructors feature the same number of arguments, you might
consider using templates instead of repeating each constructor:
class asMat
{
public:
template<class P>
asMat(P p)
: cv::Mat(p) {}
[...]
}
But of course, this is a niche solution for very special circumstances only.
With C++0x, there might be an option to use typelists for P, but I'm not
experienced enough to say this for sure.
Offline
Do constructors work differently somehow (have to be explicitly specified)?
In short, yes. You need to create constructors that mirror the arguments the parent class needs. Then do what schuay said and use the desired parent constructor in the initializer list.
Offline
First off, you create an asMat. Please do not create a cvMat, then static cast it to asMat. That'll just crash things.
You don't have to mirror the constructor if you don't want to, just call the parent's constructor like you want. For instance:
class asMat : public cvMat
{
asMat( int height, int width );
int myVariable;
}
....
asMat::asMat( int height, int width ) : cvMat( height, width, CV_8UC1), myVariable(0)
{
}
...
asMat* myAsMat = new asMat( h, w );
You can now use myAsMat wherever a cvMat* is expected and it will work correctly. This also "hard codes" the third parameter. Of course, you don't have to do this, but it's just an example.
Offline
First off, you create an asMat. Please do not create a cvMat, then static cast it to asMat. That'll just crash things.
As I understand, the crashing comes because they objects are not the same 'size' in memory. Unfortunately my asMat objects will have to begin life as cv::Mat instants, probably need some wrapper code to convert them.
And @schuay, one of the problems with searching (and I DID search) is that the wrong search terms give you nothing. I was focusing my search on general public inheritance, and none of the articles that came up mentioned constructors being special case, unfortunately.
Thanks all for the guidance. Will try it out and then mark solved.
Allan-Volunteer on the (topic being discussed) mailn lists. You never get the people who matters attention on the forums.
jasonwryan-Installing Arch is a measure of your literacy. Maintaining Arch is a measure of your diligence. Contributing to Arch is a measure of your competence.
Griemak-Bleeding edge, not bleeding flat. Edge denotes falls will occur from time to time. Bring your own parachute.
Offline
As I understand, the crashing comes because they objects are not the same 'size' in memory. Unfortunately my asMat objects will have to begin life as cv::Mat instants, probably need some wrapper code to convert them.
Some very common code for what I think your case is:
cv::Mat *crateMat(int width, int height)
{
asMat *myMat = new asMat(width, height); // This calls the constructor you make that actually calls cvMat( height, width, CV_8UC1)
// some operations in asMat but not in cvMat
return myMat;
}
or
bool crateMat(cv::Mat *mat, int width, int height)
{
asMat *myMat = new asMat(width, height); // This calls the constructor you make that actually calls cvMat( height, width, CV_8UC1)
// some operations in asMat but not in cvMat
mat = myMat;
return true; // or false based on your operations
}
or if you just want to construct and not call functions only in asMat:
cv::Mat *mat = new asMat(width, height);
If you use the functions just be sure to clean up the pointers. Also, as jdarnold said, do not use static cast the way you are. This is what dynamic_cast is for:
bool doSomethingOnlyAsMatCanDo(cv::Mat *mat)
{
asMat *myMat = dynamic_cast<asMat*>(mat);
if (myMat)
{
// some operations in asMat but not in cvMat
return true;
}
return false;
}
Offline
If cv::Mat's constructors feature the same number of arguments, you might
consider using templates instead of repeating each constructor:class asMat { public: template<class P> asMat(P p) : cv::Mat(p) {} [...] }
But of course, this is a niche solution for very special circumstances only.
With C++0x, there might be an option to use typelists for P, but I'm not
experienced enough to say this for sure.
Actually, in C++0x you will be able to say "using cv::Mat::Mat;" and be done with it.
Offline
I always thought that C++0x was just a {pipe,wet}dream the C++ people dreamed up to keep people interested in the language with the prospect of it -maybe- becoming better in the "near" future.
Last edited by Kiwi (2010-04-24 04:08:36)
Offline
My company still hasn't adopted C99, so I don't wait for new standards to come along.
Offline
I've worked on this, and come up with a solution for my situation.
Basically, I already have cv::Mat objects, because that's what is output from functions such as cv::imread. I ended up just copying the cv::Mat header and reimplementing each constructor, as well as the operator = function. Works so far without segmentation faults, and no need for static casting.
Thanks all.
Allan-Volunteer on the (topic being discussed) mailn lists. You never get the people who matters attention on the forums.
jasonwryan-Installing Arch is a measure of your literacy. Maintaining Arch is a measure of your diligence. Contributing to Arch is a measure of your competence.
Griemak-Bleeding edge, not bleeding flat. Edge denotes falls will occur from time to time. Bring your own parachute.
Offline