Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Could you explain this struct BaseConstructor to me?

36 views
Skip to first unread message

fl

unread,
Jun 12, 2015, 11:53:53 AM6/12/15
to
Hi,

I find the following code snippet on line as a tutorial for me. The first
'struct BaseConstructor' looks bizarre to me, as it does not look like a
general class/struct. Could you explain it to me?



Thanks,






//////////////////////////
struct BaseConstructor
{
BaseConstructor(int=0)
{}
};

class RealNumber;
class Complex;
class Number;
class Number
{
friend class RealNumber;
friend class Complex;
public:
Number ();
Number & operator = (const Number &n);
Number (const Number &n);
virtual ~Number();
virtual Number operator + (Number const &n) const;
void swap (Number &n) throw ();

static Number makeReal (double r);
static Number makeComplex (double rpart, double ipart);
protected:
Number (BaseConstructor);

private:
void redefine (Number *n);
virtual Number complexAdd (Number const &n) const;
virtual Number realAdd (Number const &n) const;

Number *rep;
short referenceCount;
};

Victor Bazarov

unread,
Jun 12, 2015, 12:45:13 PM6/12/15
to
On 6/12/2015 11:53 AM, fl wrote:
> I find the following code snippet on line as a tutorial for me. The first
> 'struct BaseConstructor' looks bizarre to me, as it does not look like a
> general class/struct. Could you explain it to me?

Not enough information. We see that 'Number' uses it. But we don't see
in what situation it's going to be used. What we need is to see the
code in which the protected constructor of 'Number' (which takes an
instance of 'BaseConstructor' as its argument) is going to be used.

Most likely (if I were to speculate) that 'RealNumber' and 'Complex'
classes derive from 'Number' and hence they make use of that protected
constructor of 'Number' in their own constructor. But it's unclear how
they do it without seeing the definitions of their own c-tors.

>[..]
V
--
I do not respond to top-posted replies, please don't ask

fl

unread,
Jun 12, 2015, 1:13:16 PM6/12/15
to
Thanks for your reply. Here is other code.

In fact, I have a further question when I read it. 'class Complex' is
derived from Number. In the same time, class Number is its friend class.
I see this kind of thing the first time. A child class needs its parent
(base) class to operate on it?


Thanks,

..............
class Complex : public Number
{
friend class RealNumber;
friend class Number;

Complex (double d, double e);
Complex (const Complex &c);
virtual ~Complex ();

virtual Number operator + (Number const &n) const;
virtual Number realAdd (Number const &n) const;
virtual Number complexAdd (Number const &n) const;
double rpart, ipart;
};

class RealNumber : public Number
{
friend class Complex;
friend class Number;

RealNumber (double r);
RealNumber (const RealNumber &r);
virtual ~RealNumber ();

virtual Number operator + (Number const &n) const;
virtual Number realAdd (Number const &n) const;
virtual Number complexAdd (Number const &n) const;

double val;
};

/// Used only by the letters.
Number::Number (BaseConstructor): rep (0), referenceCount (1)
{}

/// Used by user and static factory functions.
Number::Number () : rep (0), referenceCount (0)
{}

/// Used by user and static factory functions.
Number::Number (const Number &n): rep (n.rep), referenceCount (0)
{
cout << "Constructing a Number using Number::Number\n";
if (n.rep)
n.rep->referenceCount++;
}

Number Number::makeReal (double r)
{
Number n;
n.redefine (new RealNumber (r));
return n;
}

Number Number::makeComplex (double rpart, double ipart)
{
Number n;
n.redefine (new Complex (rpart, ipart));
return n;
}

Number::~Number()
{
if (rep && --rep->referenceCount == 0)
delete rep;
}

Number & Number::operator = (const Number &n)
{
cout << "Assigning a Number using Number::operator=\n";
Number temp (n);
this->swap (temp);
return *this;
}

Victor Bazarov

unread,
Jun 12, 2015, 1:34:59 PM6/12/15
to
In order to convince yourself about the necessity of doing that (making
the derived a friend of the base and vice versa), try commenting out the
'friend' declaration and see what errors about access you get when
compiling.

> I see this kind of thing the first time. A child class needs its parent
> (base) class to operate on it?

The derived classes have no public members. All members are therefore
private. In order to even construct an object of that type you need to
either be a member or be a friend.
In order to compile this particular line, 'Number' has to be a friend of
'RealNumber'.

> return n;
> }
>
> Number Number::makeComplex (double rpart, double ipart)
> {
> Number n;
> n.redefine (new Complex (rpart, ipart));

In order to compile this particular line, 'Number' has to be a friend of
'Complex'.

> return n;
> }
>
> Number::~Number()
> {
> if (rep && --rep->referenceCount == 0)
> delete rep;
> }
>
> Number & Number::operator = (const Number &n)
> {
> cout << "Assigning a Number using Number::operator=\n";
> Number temp (n);
> this->swap (temp);
> return *this;
> }
>

I am still unsure about the 'BaseConstructor' role, but I think it's to
prevent some unpleasantness, but which unpleasantness, is still foggy
to me and I'm too lazy to take your code and compile it while playing
with c-tors and access specifiers; you can do it.

Try redefining Number(BaseConstructor) to be explicit Number(int).

fl

unread,
Jun 14, 2015, 8:09:56 PM6/14/15
to
After reading a description about the above code snippet, I find that it is
possible helpful on the role of BaseConstructor. The code author try to
mimic a pure object-oriented language with C++. But I still cannot
understand the intention of BaseConstructor. I feel the code is
interesting to learn the technique involved. Could you help me on the role
of BaseConstructor?

Thanks,


.................
Motivation
In pure object-oriented languages like Smalltalk, variables are run-time
bindings to objects that act like labels. Binding a variable to an object
is like sticking a label on it. Assignment in these languages is analogous
to peeling a label off one object and putting it on another. On the other
hand, in C and C++, variables are synonyms for addresses or offsets instead
of being labels for objects. Assignment does not mean re-labelling, it
means overwriting old contents with new one. Algebraic Hierarchy idiom uses
delegated polymorphism to simulate weak variable to object binding in C++.
Algebraic Hierarchy uses Envelope Letter idiom in its implementation. The
motivation behind this idiom is to be able write code like the one below.


Number n1 = Complex (1, 2); // Label n1 for a complex number
Number n2 = Real (10); // Label n2 for a real number
Number n3 = n1 + n2; // Result of addition is labelled n3
Number n2 = n3; // Re-labelling

fl

unread,
Jun 14, 2015, 9:48:56 PM6/14/15
to
On Friday, June 12, 2015 at 8:53:53 AM UTC-7, fl wrote:
My another question is about '(int=0)' inside the struct. I cannot
understand it because 'int' is a reserved word. I never see such usage
before. Can you explain it to me?

Thanks,


struct BaseConstructor
{
BaseConstructor(int=0)
{}
};

Richard Damon

unread,
Jun 14, 2015, 10:23:26 PM6/14/15
to
When declaring a function (or a constructor), as opposed to defining it,
the declaration is not required to include the variable names of the
parameters (as they aren't important).

You are also allowed to provide default values for the parameter if it
isn't provided.

A fuller version of the declaration would be

BaseConstructor(int i=0);

Because this constructor can be called with no parameters, it can be
used as the default constructor, which will act exactly like calling the
constuctor with a parameter of 0 (the default value defined)

Paavo Helde

unread,
Jun 15, 2015, 3:06:26 AM6/15/15
to
fl <rxj...@gmail.com> wrote in
news:066dbb93-ab01-4680...@googlegroups.com:

>> //////////////////////////
>> struct BaseConstructor
>> {
>> BaseConstructor(int=0)
>> {}
>> };

[...]

>> class Number
>> {
>> protected:
>> Number (BaseConstructor);
[...]
>> private:
>> Number *rep;
>> short referenceCount;
>> };
>
> After reading a description about the above code snippet, I find that
> it is possible helpful on the role of BaseConstructor. The code author
> try to
> mimic a pure object-oriented language with C++. But I still cannot
> understand the intention of BaseConstructor. I feel the code is
> interesting to learn the technique involved. Could you help me on the
> role of BaseConstructor?

It appears BaseConstructor is only used in a protected constructor, so it
probably is meant as some kind of communication detail between derived
and base classes. It is not clear from these code examples how it is
used.

> .................
> Motivation
> In pure object-oriented languages like Smalltalk, variables are
> run-time
> bindings to objects that act like labels. Binding a variable to an
> object is like sticking a label on it. Assignment in these languages
> is analogous to peeling a label off one object and putting it on
> another. On the other hand, in C and C++, variables are synonyms for
> addresses or offsets instead of being labels for objects. Assignment
> does not mean re-labelling, it means overwriting old contents with
> new one. Algebraic Hierarchy idiom uses delegated polymorphism to
> simulate weak variable to object binding in C++. Algebraic Hierarchy
> uses Envelope Letter idiom in its implementation. The motivation
> behind this idiom is to be able write code like the one below.
>
>
> Number n1 = Complex (1, 2); // Label n1 for a complex number
> Number n2 = Real (10); // Label n2 for a real number
> Number n3 = n1 + n2; // Result of addition is labelled n3
> Number n2 = n3; // Re-labelling

I would guess this passage is more about the rep and referenceCount
members. It is interesting to not that here both the "envelope" and
"letter" parts are both based on the same class (Number), which seems to
make the design much more complicated than needed. It is probably meant
for "automagically" allowing code like that:

Real x(10);
Complex y(1, 2);
Number z = x + y;

However, then also this is allowed:

x = y;

This seems quite confusing - is x now Real or Complex?


hth
Paavo

Victor Bazarov

unread,
Jun 15, 2015, 8:29:15 AM6/15/15
to
I think the OP's question is, why have 'BaseConstructor' at all. I am
perhaps too dense to try to think for the designer of the code, and so I
am not sure I divined the reason for having 'BaseConstructor' and to use
it to create a Number instance. I have a sneaky suspicion that it has
something to do with possibly initializing Number from an int, and to
prohibit such construction, which would be assisted in some way by
having a BaseConstructor convertible from an int. But to confirm that
one would need to take out BaseConstructor and see the effects, and I am
simply too lazy to experiment.
0 new messages