Class-related queries [was: Re: 'Undefined reference' linking errors]
Joseph Wakeling
joseph.wakeling at gmail.com
Fri Apr 9 06:56:02 PDT 2010
Ali Çehreli wrote:
> I have experience with C++ and still don't understand why opCall exists.
> :) I think I heard that opCall was needed to create struct objects
> before structs had constructors in D.
>
> Now structs do have constructors, which sometimes conflict with opCall. :)
I also have some C++ experience, but it seems to be confusing as much as
complementary with respect to D ... :-)
Current source of confusion relates to declaring objects of a class whose
constructor takes input -- confusion because I can write,
class Foo
{
int x;
uint y;
this()
{
x = -1;
y = 2;
}
}
void main()
{
Foo f;
}
and have no problem, but if instead the constructor is,
this(int z)
{
x = z;
y = 2;
}
... it seems like I have to write instead,
auto f = new Foo(-1);
... and if I write as per C++,
Foo f(-1);
... I get back a compiler error: "found 'f' when expecting ';' following
'statement'". Am I right in thinking that the 'new' syntax is necessary when the
class has a constructor which takes input?
This creates confusion also because in C++ one associates 'new' with dynamic
allocation of memory, and it requires a consequent 'delete' statement. I know
that D has GC, and I know that it also has 'delete' statements, but ... this one
is 'ouch' for me :-P
In my own code (cleaned up, attached following this email, and now working), I
note the line,
auto aw = new AvgWeighted(ratings,reputationUser,reputationObject);
where if I write instead,
AvgWeighted aw(ratings,reputationUser,reputationObject);
... I get the error:
Error: ratings is used as a type
Error: cannot have parameter of type void
Error: reputationUser is used as a type
Error: cannot have parameter of type void
Error: reputationObject is used as a type
Error: cannot have parameter of type void
... which is difficult to understand, but I presume it relates to the fact that an
array is a class and not a value.
Apologies if these are relatively trivial questions -- I am sure they will all
become clearer once Andrei Alexandrescu's book is out ... :-)
Thanks & best wishes,
-- Joe
///////// My code ....
struct Rating
{
uint u; // user ID
uint o; // object ID
double r; // rating value
}
class Reputation
{
this() {}
this(ref Rating[] ratings,
ref double[] reputationUser,
ref double[] reputationObject) {}
}
class AvgWeighted : Reputation
{
double[] weightSum;
this(){}
this(ref Rating[] ratings,
ref double[] reputationUser,
ref double[] reputationObject)
{
opCall(ratings,reputationUser,reputationObject);
}
void opCall(ref Rating[] ratings,
ref double[] reputationUser,
ref double[] reputationObject)
{
weightSum.length = reputationObject.length;
weightSum[] = 0;
reputationObject[] = 0;
foreach(ref Rating r; ratings) {
reputationObject[r.o] += reputationUser[r.u]*r.r;
weightSum[r.o] += reputationUser[r.u];
}
foreach(uint o, ref double r; reputationObject)
r /= weightSum[o];
}
}
class AvgArithmetic : AvgWeighted
{
this(ref Rating[] ratings,
ref double[] reputationUser,
ref double[] reputationObject)
{
opCall(ratings,reputationUser,reputationObject);
}
void opCall(ref Rating[] ratings,
ref double[] reputationUser,
ref double[] reputationObject)
{
reputationUser[] = 1;
super.opCall(ratings,reputationUser,reputationObject);
}
}
void main()
{
Rating[] ratings;
double[] reputationUser;
double[] reputationObject;
foreach(uint u; 0..999)
reputationUser ~= 0.1*(u%3);
reputationObject.length = 1;
reputationObject[] = 0;
foreach(uint u;0..reputationUser.length) {
Rating _r = {u,0,(u%3)};
writefln("%u %g",_r.u,_r.r);
ratings ~= _r;
}
auto aw = new AvgWeighted(ratings,reputationUser,reputationObject);
aw(ratings,reputationUser,reputationObject);
foreach(double o; reputationObject)
writefln("%g",o);
}
More information about the Digitalmars-d-learn
mailing list