:: Scope qualifier misunderstanding.

B

bardos

Hello, I'm relatively new to C++ so I hope you can help clear up a
problem. You may well be able to do so before checking the example, so
don't be put off by the long post :) The problem regards the usage and
effect of the :: scope qualifier. I'm converting a Java app to C++ and
need to find the equivalent of using the Java 'super' keyword. This
executes the 'superclass's constructor (with possibly different
arguments from the derived constructor). I thought I would do this by
using the C++ :: operator, to pick the required base constructor from
within the derived class. Eg,

DerivedClass::DerivedClass(int x)
{
BaseClass::BaseClass(x , NULL, NULL); // Call different
constructor.
}

I was hoping this would set the values in the derived class using the
base constructor.

This compiles fine, but any operation carried out in the base class
seem to have no effect on the dervied class. Does anyone know why this
is, and how to remedy this? I've enclosed an example.

The program has 3 classes, base1, base 2 (inherits base 1) and derived
(inherits base2). Each class has one int (b1,b2 and d respectively).

Using :: to call methods to set values b1 and b2 in base1 and base2
has no effect, leaving the values undefines inthe derived class.
The program outputs -842150451 -842150451 3 for the 3 values, instead
of the expected 1,2,3.

I would really appretiate any help with my misunderstanding,

Regards,

Steve.


// EXAMPLE CODE.

// Base 1 declaration.

class base1
{
public:
base1(){}; // Default constructor.
base1(int);
int b1;
};

base1::base1(int i)
{
b1 = i;
}

// Base 2 declaration, uses base1 as base class.

class base2 :public base1
{
public:
base2(){}; // Default constructor.
base2(int);
int b2;
};

base2::base2(int i)
{
b2 = i;
base1::base1(1);
}

// Derived class, uses base2 (and therefore class1) as base classes.

class derived : public base2
{
public:
derived(int);
int d;
};

derived::derived(int i)
{
d = i;
base2::base2(2);
}

void main(int argc,char *argv[])
{
derived *d;

d = new derived(3);
printf("%d %d %d ",d->b1,d->b2,d->d);
}
 
S

Serge Paccalin

Le samedi 28 août 2004 à 09:52:55, bardos a écrit dans comp.lang.c++ :
Hello, I'm relatively new to C++ so I hope you can help clear up a
problem. You may well be able to do so before checking the example, so
don't be put off by the long post :) The problem regards the usage and
effect of the :: scope qualifier. I'm converting a Java app to C++ and
need to find the equivalent of using the Java 'super' keyword. This
executes the 'superclass's constructor (with possibly different
arguments from the derived constructor). I thought I would do this by
using the C++ :: operator, to pick the required base constructor from
within the derived class. Eg,

DerivedClass::DerivedClass(int x)
{
BaseClass::BaseClass(x , NULL, NULL); // Call different
constructor.
}

I was hoping this would set the values in the derived class using the
base constructor.

This compiles fine, but any operation carried out in the base class
seem to have no effect on the dervied class. Does anyone know why this
is, and how to remedy this? I've enclosed an example.

I think you want:

DerivedClass::DerivedClass(int x)
: BaseClass(x , NULL, NULL) // Call different constructor.
{
// rest of init there.
}

derived::derived(int i)
: base2(2)
{
d = i;
}

--
___________ 2004-08-28 10:22:59
_/ _ \_`_`_`_) Serge PACCALIN -- sp ad mailclub.net
\ \_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
 
O

Old Wolf

bardos said:
I'm converting a Java app to C++ and need to find the equivalent of
using the Java 'super' keyword. This executes the 'superclass's
constructor (with possibly different arguments from the derived
constructor).

In C++, the base class constructors all get called automatically,
before the body of the derived class constructor is executed:
DerivedClass::DerivedClass(int x)
{

By this point, the base class constructors and the member objects
have all been initialized already.
BaseClass::BaseClass(x , NULL, NULL);

Actually this creates a new un-named object of type BaseClass,
which is then destroyed immediately. It is similar to:

BaseClass foo(x, NULL, NULL);
}

I was hoping this would set the values in the derived class using the
base constructor.

You need to specify arguments for the base class constructors before
the opening { of the derived constructor (if you don't, then the default
constructors will be called). In fact you can specify initialization
for any member objects and/or base classes at this point:

DerivedClass::DerivedClass(int x)
: BaseClass(x, NULL, NULL), member_int(5)
{
// EXAMPLE CODE.

class base1
{
public:
base1(){}; // Default constructor.

This semicolon isn't required (some people would say, the code is
easier to read without it).
base1(int);
int b1;
};

base1::base1(int i)
{
b1 = i;
}

Preferable is:
base1::base1(int it)
: b1(i)
{
}

(Practically speaking, there is no difference, but if 'b1' had been
a class type with a constructor, then your way would have
constructed 'b1' with the default constructor first, and then
assigned 'i' to it: a waste of time).
base2::base2(int i)
{
b2 = i;
base1::base1(1);
}

Similarly:

base2::base2(int i)
: base1(1), b2(i) {}

Note that the base classes get initialized before the member objects,
regardless of what order you list things here, ie. that would have
been the same as:
: b2(i), base1(1) {}
void main(int argc,char *argv[])

main() must return an int in C++ (many compilers would refuse to
compile your example)
{
derived *d;

d = new derived(3);
printf("%d %d %d ",d->b1,d->b2,d->d);

Coming from a Java background you may be unaware that in C++ you
can create objects with: "Type name(args);" , you should avoid
using "new" if possible. If you "new" an object you have to
"delete" it later, but if you create it with the "Type name(args)"
form, then it is automatically deleted when it goes out of scope.

Also, C++ programs should end their output with a newline.

int main()
{
derived d(3);
printf("%d %d %d \n", d.b1, d.b2, d.d);
// or: std::cout << d.b1 << " " << d.b2 << " " << d.b3 << "\n";
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top