James Kanze
11/15/2008 9:51:00 AM
On Nov 15, 12:59 am, Salt_Peter <pj_h...@yahoo.com> wrote:
> On Nov 14, 4:57 pm, "Edward Jensen" <edw...@jensen.invalid> wrote:
> > I have the following static arrays of different size in a class:
> > in header:
> > static double w2[2], x2[2];
> > static double w3[3], x3[3];
> > static double w4[4], x4[4];
> > in GaussLegendre.cpp:
> > double GaussLegendre::w2[2] = {1.0, 1.0};
> > double GaussLegendre::x2[2] = {-0.577350269189625, 0.577350269189625};
> > double GaussLegendre::w3[3] = {0.555555555555556, 0.8888888888888889,
> > 0.555555555555556};
> > double GaussLegendre::x3[3] = {-0.774596669241483, 0.0, 0.774596669241483};
> > double GaussLegendre::w4[4] = {0.347854845137453, 0.652145154862546,
> > 0.652145154862546, 0.347854845137453};
> > double GaussLegendre::x4[4] = {-0.861136311594053, -0.339981043584856,
> > 0.339981043584856, 0.861136311594053};
So presumably that bit in header was within the defintion of the
class GaussLegendre.
> > Now I want to create a static array of pointers of x2, x3,
> > x4 and w2,w2,w4. I thought I could do that with just
> > declaring statis double* x[3] in my header and the following
> > in .cpp:
> > double* GaussLegendre::x[3] = {&GaussLegendre::x2, &GaussLegendre::x3,
> > &GaussLegendre::x4};
> > but I get the following error: cannot convert from 'double (*)[2]' to
> > 'double *
You should get an error about defining a variable twice, and/or
defining it with a different type than it was declared with.
> > Why is that and how can it be done?
> You can point to a double using a double*, you certainly can't
> point to an array of doubles of varying sizes. You can however
> point to the first element of each array. Something as
> follows:
> double* GaussLegendre::x[3] = { &GaussLegendre::x2[0],
> &GaussLegendre::x3[0],
> &GaussLegendre::x4[0] };
That's certainly legal, but it's far more idiomatic to use the
implicit conversion of array to pointer here, as Sam suggested.
While it may be a misfeature, it's use is ubiquious, and
unavoidable if you are using C style arrays.
> However, the elements of x know nothing about the contents of the
> arrays that are part of.
Which is as it should be. (But I think you're trying to say
something else. You surely don't mean that the value in x[1]
should know something about x as a whole.)
> To solve the issue, use dynamic containers. Lets take a
> std::deque of std::vectors< double > for example (ignore the
> operator<< for now - it just displays the populated
> containers). Notice how much simpler coding without pointers
> is.
As a general rule, std::vector should be preferred, so his
double[] would become std::vector<double>, and he really can
have an array of pointers to arrays, std::vector< std::vector<
double >* >. I'd want to know more about his particular use,
however, before doing that here. I have a sneaky suspicion that
he's forgotten the const, and there is one place where C style
arrays are better: they allow static initialization. If all of
these tables are in fact const, it might make more sense (and it
would certainly require less code) to leave them as C style
arrays, i.e. something like:
double const GaussLegendre::w2[2] = {1.0, 1.0};
// ...
double const *const GaussLegendre::x2[2] = { ... } ;
Typically, I'd also leave off the size of the dimension, and
let the compiler calculate it. But again, I'm not sure here; I
think the actual size may be important, in which case, it's
better explicitly stating it.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34