473,386 Members | 1,720 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

use base class constructors always

hi,
In the following code, I would like not to have to declare the
constructors in bar ( either the default or the (int a) constructor ).
When I remove them, bar has no idea of construction with an int, so I
get compile errors. I currently have to declare them for every class
inheriting foo, and it would be much nicer just with the init. Is there
a nice way of doing this? I am currently using a
macro, like CONSTRUCTOR(bar) which feels a bit squiffy to me.
Also, if I'm not pushing my luck I would like some way to make the init
pure virtual to force implementation in inheritors, without getting the
linker error for foo::init that I get when I try.
thanks,
iain

class foo
{
public:
foo() {}
foo( int a ) {init(a);}
virtual void init ( int a ) {};
};

class bar: public foo
{
public:
bar() {}
bar( int a ):foo(a) {}
virtual void init( int a ){/*etc.*/}
};

void main()
{
bar a( 1 );
bar b;
b.init( 2 );
}

Jul 23 '05 #1
4 1429
pixelbeast wrote:
In the following code, I would like not to have to declare the
constructors in bar ( either the default or the (int a) constructor ).
When I remove them, bar has no idea of construction with an int, so I
get compile errors.
Post the code which gives you the compile errors, don't post speculation.
I currently have to declare them for every class
inheriting foo, and it would be much nicer just with the init.
'init' is a deceitful name. True initialisation happens during object's
construction. If you don't want to initialise during construction, it's
your right, but your base class object ('foo' part of any derived class)
will be initialised (or at least attempted at initialising) when the
derived class object is constructed, not when 'init' is called.
Is there
a nice way of doing this?
A nice way of doing what, exactly?
I am currently using a
macro, like CONSTRUCTOR(bar) which feels a bit squiffy to me.
Where? I don't see any 'CONSTRUCTOR' macro in the code posted.
Also, if I'm not pushing my luck I would like some way to make the init
pure virtual to force implementation in inheritors, without getting the
linker error for foo::init that I get when I try.
Again, what linker errors? Post the code that produces the errors.
thanks,
iain

class foo
{
public:
foo() {}
foo( int a ) {init(a);}
Here the 'init' of the class 'foo' will be called, not the 'init' of
the most derived class (as you might hope).
virtual void init ( int a ) {};
};

class bar: public foo
{
public:
bar() {}
bar( int a ):foo(a) {}
virtual void init( int a ){/*etc.*/}
};

void main()
There is no 'void main' in C++, BTW.
{
bar a( 1 );
bar b;
b.init( 2 );
}

V
Jul 23 '05 #2
i think you are right ofcourse, I need to re-evaluate this, the
splitting of constructors and inits was done a long time ago in my
codebase, but looking at the current situation, and the problems it is
causing, I will go back and investigate why I did it.

for completeness, you requested code that causes the compile errors,
The following code (removing the constructors from bar)....

class foo
{
public:
foo() {}
foo( int a ) {init(a);}
virtual void init ( int a ) {};
};

class bar: public foo
{
public:
//comment bar() {}
//comment bar( int a ):foo(a) {}
virtual void init( int a ){}
};

void main()
{
bar a( 1 );
bar b;
b.init( 2 );
}

... gives the following error..
d:\dev\test\test\t.cpp(20) : error C2664: 'bar::bar(const bar &)' :
cannot convert parameter 1 from 'int' to 'const bar &'
Reason: cannot convert from 'int' to 'const bar'
No constructor could take the source type, or constructor
overload resolution was ambiguous

... and trying to make "init" pure virtual as follows...

class foo
{
public:
foo() {}
foo( int a ) {init(a);}
virtual void init ( int a ) =0;
};

class bar: public foo
{
public:
bar() {}
bar( int a ):foo(a) {}
virtual void init( int a ){}
};

void main()
{
bar a( 1 );
bar b;
b.init( 2 );
}

... gives the following linker error...
t.obj : error LNK2019: unresolved external symbol "public: virtual void
__thiscall foo::init(int)" (?init@foo@@UAEXH@Z) referenced in function
"public: __thiscall foo::foo(int)" (??0foo@@QAE@H@Z)
Debug/test.exe : fatal error LNK1120: 1 unresolved externals

.... finally the macro i was attempting to use, was equivalent to the
one used in following, where I was testing your analysis of my init...
#define CONSTRUCTORS(_name) \
_name() {} \
_name(int a) : foo(a) {}

class foo
{
public:
foo() {}
foo( int a ) {init(a);}
virtual void init ( int a ) {};
};

class bar: public foo
{
public:
CONSTRUCTORS(bar)
virtual void init( int a ){ val = a;}
int val;
};

void main()
{
bar a( 1 );
bar b;
b.init( 2 );

bar c(3); // doesn't work - as Victor predicted.
// virtual init in foo is called
bar d;
d.init(3);

bar e;
foo *pe = &e;
pe->init(3);
}
.... however, as is obvious - my splitting of contructor
responsibilities is producing problems where there shouldn't be any and
I shall be changing it .

Thanks for being frank, sorry about the void main();

Jul 23 '05 #3
pixelbeast wrote:
i think you are right ofcourse, I need to re-evaluate this, the
splitting of constructors and inits was done a long time ago in my
codebase, but looking at the current situation, and the problems it is
causing, I will go back and investigate why I did it.

for completeness, you requested code that causes the compile errors,
The following code (removing the constructors from bar)....

class foo
{
public:
foo() {}
foo( int a ) {init(a);}
virtual void init ( int a ) {};
};

class bar: public foo
{
public:
//comment bar() {}
//comment bar( int a ):foo(a) {}
virtual void init( int a ){}
};

void main()
{
bar a( 1 );
bar b;
b.init( 2 );
}

.. gives the following error..
d:\dev\test\test\t.cpp(20) : error C2664: 'bar::bar(const bar &)' :
cannot convert parameter 1 from 'int' to 'const bar &'
Reason: cannot convert from 'int' to 'const bar'
No constructor could take the source type, or constructor
overload resolution was ambiguous
What else to expect? You haven't defined a constructor in the 'bar'
class which would accept an argument of type 'int', how should the
compiler know what you want to do when you write

bar a( 1 );

??? Remember, constructors are *not* inherited.
.. and trying to make "init" pure virtual as follows...

class foo
{
public:
foo() {}
foo( int a ) {init(a);}
Again, this would call 'foo::init', which is pure, and you'll have
undefined behaviour.
virtual void init ( int a ) =0;
};

class bar: public foo
{
public:
bar() {}
bar( int a ):foo(a) {}
virtual void init( int a ){}
};

void main()
{
bar a( 1 );
bar b;
b.init( 2 );
}

[...]

... however, as is obvious - my splitting of contructor
responsibilities is producing problems where there shouldn't be any and
I shall be changing it .

Thanks for being frank, sorry about the void main();


Don't be sorry, just get rid of it. C++ has no 'void main'...

V
Jul 23 '05 #4
pixelbeast wrote:
hi,
In the following code, I would like not to have to declare the
constructors in bar ( either the default or the (int a)
constructor ). When I remove them, bar has no idea of
construction with an int, so I get compile errors. I
currently have to declare them for every class inheriting
foo, and it would be much nicer just with the init. Is there
a nice way of doing this?
Unfortunately, no. I believe that the standards committee is
looking at ways of adding this to future versions of the
language.
class foo
{
public:
foo() {}
foo( int a ) {init(a);}
virtual void init ( int a ) {};
};

class bar: public foo
{
public:
bar() {}
bar( int a ):foo(a) {}
virtual void init( int a ){/*etc.*/}
};


Something you might not be aware of: when you construct
a bar from an int, eg:

bar b(1);

then it will call foo::init, and bar::init will never be
called. The virtual function mechanism doesn't kick in
until after the object has been constructed. In other
words, the call to 'init' in foo(int) does not try to
call init in any derived classes, because the derived
object has not yet been constructed.

Jul 23 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Martin Magnusson | last post by:
Hi! I have a class with a private member which is a pointer to an abstract class, which looks something like this: class Agent { public: void Step( Base* newB ); private:
23
by: Fabian Müller | last post by:
Hi all, my question is as follows: If have a class X and a class Y derived from X. Constructor of X is X(param1, param2) . Constructor of Y is Y(param1, ..., param4) .
3
by: J.J. Feminella | last post by:
(Please disregard the previous message; I accidentally sent it before it was completed.) I have source code similar to the following. public class Vehicle { protected string dataV; // ......
3
by: hazz | last post by:
The following classes follow from the base class ' A ' down to the derived class ' D ' at the bottom of the inheritance chain. I am calling the class at the bottom, "public class D" from a client...
12
by: Chris | last post by:
Hi I am trying to create a base class with the Protected keyword Protected MustInherit Class MyBaseClas .. .. End Clas And I got an error saying something like the Protected keyword...
2
by: norton | last post by:
Hello, May i know if there any ways to inherits a constructor from the base class? For Example i have a abstract class called User and a Customer class is inherits from User, and the base...
1
by: John | last post by:
Hi, Maybe someone can help me with the following: "The first task by any derived class constructor is to call it’s direct or indirect base class constructor implicitly or explicitly", reads the...
26
by: nyathancha | last post by:
Hi, How Do I create an instance of a derived class from an instance of a base class, essentially wrapping up an existing base class with some additional functionality. The reason I need this is...
11
by: Aflj | last post by:
This code won't compile (two compilers tried, gcc and VC++, both of recent versions, but I don't remember them exactly): class C1 { public: void M1(int i) {} }; class C2: public C1
2
by: Josh Valino | last post by:
If I have a base class that has one constructor, is the only way that that constructor will get called be by having no constructors in my derived classes or explicitly calling base() in my derived...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.