By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,331 Members | 1,359 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,331 IT Pros & Developers. It's quick & easy.

:: Scope qualifier misunderstanding.

P: n/a
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);
}
Jul 22 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
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
Jul 22 '05 #2

P: n/a
bardos <> wrote:
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";
}
Jul 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.