I'm fairly new to C++ and VC++, but for the most part it seems to do most of
the same things that can be done in Java, with just some syntactic and
structural adjustments. However, one thing I haven't been able to figure out
is how to call one constructor from another within a class. It's easy enough
to call the base class's constructor from the derived class, but that's not
what I'm trying to do.
For example, in Java (or J#) it's easy to do this:
public class Circle
{
private int PointX;
private int PointY;
private int Radius;
public Circle()
{
this.PointX = 0;
this.PointY = 0;
this.Radius = 0;
}
public Circle(int x, int y)
{
this();
this.PointX = x;
this.PointY = y;
}
public Circle(int x, int y, int r)
{
this(x, y);
this.Radius = r;
}
}
However, trying to do the same thing in VC++ doesn't work:
// Sphere.h (partial file)
class Sphere
{
public:
Sphere(void);
Sphere(int x, int y);
Sphere(int x, int y, int r);
~Sphere(void);
private:
int PointX;
int PointY;
int Radius;
};
// Circle.cpp (partial file)
#include ".\circle.h "
Circle::Circle( void)
{
this->PointX = 0;
this->PointY = 0;
this->Radius = 0;
}
Circle::Circle( int x, int y)
{
Circle();
this->PointX = x;
this->PointY = y;
}
Circle::Circle( int x, int y, int r)
{
Circle(x, y);
this->Radius = r;
}
In the C++ version, I also tried using this() instead of Circle(), which
caused a compiler error. I also tried doing it without the this-> specifier,
which made no difference. The end result if you call the second constructor
is that the X and Y values have been set, and the Radius is uninitialized.
If you use the third constructor, you get exactly the opposite results. (And
I don't mean they have values of zero; looking at them with the debugger, I
see values of -842150451 for the uninitialized members.)
So is there any way in C++ to let one constructor build on another like
this?
Thanks for any help.
Nov 17 '05
31 5196
"Hendrik Schober" <Sp******@gmx.d e> wrote in message
news:e8******** *****@tk2msftng p13.phx.gbl... Ken Alverson <US********@Alv erson.net> wrote: "Hendrik Schober" <Sp******@gmx.d e> wrote in message news:%2******** ********@TK2MSF TNGP11.phx.gbl. .. Note that C++ has default parameters which, AFAIK, where introduced especially to solve this problem:
Default parameters were introduced because, at the time, there was no such thing as method overloading. They just happen to also solve some of the simpler cases of redundant constructors.
"The original motivation for default parameters was exactly because a ctor cannot call another ctor for the same type." (Francis Glassborow) http://www.google.de/groups?selm=pM5...on.demon.co.uk I don't have D&E handy here, but I believe that function overloading was among the very first features of C++. Wasn't there even an 'overload' keyword (considered?) ones but later dismissed because it wasn't needed?
OTOH, I know the first one only from Francis' posting and the second only from my memory, so i might be wrong.
I could be wrong, and I'm more than willing to admit if I am, but I remember
pretty clearly reading somewhere that the reason we still had default
parameters was backward compatibility with pre-overload code. If overloads
had existed from the get-go, it was argued that default parameters would never
have been created. I'll see if I can find where I read that and see if it has
any credibility.
Ken
This is something that kinda sorta might work, but it's horribly
inefficient: Circle::Circle( int x, int y, int r) {
//> Circle(x, y);
Circle temp(x, y);
std::swap(*this , temp); // temp now contains our unitialised values
// and will quietly disappear at the end of
// this scope.
this->Radius = r; }
I don't recommend this at all. It is cheaper and more readable to hand off
to an init() function. And more efficient than your example as you only set
values once [if we ignore the fact that the members have already been
default initialised to garbage in every case]:
Circle::Circle( )
{ init(0, 0, 0); }
Circle::Circle( int x, int y)
{ init(x, y, 0); }
Circle::Circle( int x, int y, int r)
{ init(x, y, r); }
What you are attempting is a Java idiom not a C++ one. Don't be mislead by
superficial similarities in syntax; they are totally different animals. You
should definitely prefer member initialiser lists:
Circle::Circle( )
: PointX(0), PointY(0), Radius(0)
{ }
Circle::Circle( int x, int y)
: PointX(x), PointY(y), Radius(0)
{ }
Circle::Circle( int x, int y, int r)
: PointX(x), PointY(y), Radius(r)
{ }
FWIW I learnt Java and C++ the other way around. I find I miss little
things, too: templates, RAII, type safe containers... Ho hum.
Arnold the Aardvark http://www.codeproject.com/cpp/garbage_collect.asp
Ken Alverson wrote: I could be wrong, and I'm more than willing to admit if I am, but I remember pretty clearly reading somewhere that the reason we still had default parameters was backward compatibility with pre-overload code.
"Given general function overloading, default arguments are logically
redundant and at best a minor notational convenience. However, C with
Classes had default argument lists for years before general overloading
became avilable in C++." - Stroustrup, D&E, S:2.12.2.
Arnold the Aardvark http://www.codeproject.com/cpp/garbage_collect.asp
"Arnold the Aardvark" <no@way.com> wrote in message
news:bv******** ***********@new s.demon.co.uk.. . Ken Alverson wrote:
I could be wrong, and I'm more than willing to admit if I am, but I remember pretty clearly reading somewhere that the reason we still had default parameters was backward compatibility with pre-overload code.
"Given general function overloading, default arguments are logically redundant and at best a minor notational convenience. However, C with Classes had default argument lists for years before general overloading became avilable in C++." - Stroustrup, D&E, S:2.12.2.
That's the quote I remember, thanks!
Ken
Ken Alverson <US********@Alv erson.net> wrote: [...] "Given general function overloading, default arguments are logically redundant and at best a minor notational convenience. However, C with Classes had default argument lists for years before general overloading became avilable in C++." - Stroustrup, D&E, S:2.12.2. That's the quote I remember, thanks!
So I got it wrong.
Now, wait... No! Francis got it wrong! :)
Ken
Schobi
P.S.: Actually... No. This quote still doesn't
say they were not introduced to help with
the problem of redundant constructor code.
-- Sp******@gmx.de is never read
I'm Schobi at suespammers dot org
"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Hendrik Schober wrote: Ken Alverson <US********@Alv erson.net> wrote: [...] > "Given general function overloading, default arguments are logically > redundant and at best a minor notational convenience. However, C with > Classes had default argument lists for years before general overloading > became avilable in C++." - Stroustrup, D&E, S:2.12.2.
That's the quote I remember, thanks!
So I got it wrong. Now, wait... No! Francis got it wrong! :)
Ken
Schobi
P.S.: Actually... No. This quote still doesn't say they were not introduced to help with the problem of redundant constructor code.
I didn't have time to skim the whole book, you understand,
but there was something about :
"The default argument list was a very late addition to
the class definition. It was added to curb the proliferation
of identical 'standard argument lists' for class objects
passed as function arguments, ... they can be used to
make class object declarations less verbose and more
similar to struct declarations." - same section.
He's lost me a bit there. :-( 'standard argument lists'?
Arnold the Aardvark http://www.codeproject.com/cpp/garbage_collect.asp
Ken Alverson wrote: "Mihajlo Cvetanovic" <ma*@RnEeMtOsVe Et.co.yu> wrote in message news:40******** ******@RnEeMtOs VeEt.co.yu... There is something called "placement new" which in this context behaves exactly like calling one c-tor from another, but programmers are discouraged from using it.
Placement new is only designed to be used on uninitialized memory. By the time you get to the first line of a constructor, you have a semi-valid object in that memory that would be wiped out.
You'll sometimes see people doing bizarre (but legal) things like:
this->~Foo();
new (this) Foo();
To "re-initialize" an object. You can use this same technique to "call" one
constructor from within another. But don't.
-cd
"Carl Daniel [VC++ MVP]" <cp************ *************** **@mvps.org.nos pam>
wrote in message news:uW******** *****@TK2MSFTNG P11.phx.gbl... Ken Alverson wrote: Placement new is only designed to be used on uninitialized memory. By the time you get to the first line of a constructor, you have a semi-valid object in that memory that would be wiped out.
You'll sometimes see people doing bizarre (but legal) things like:
this->~Foo(); new (this) Foo();
Is that actually legal though? I thought about it, but I wasn't sure if it
was legal to call the destructor before the constructor completed. Either way
it fails if the type of this is really a derived class and not Foo.
Regardless of whether or not it is legal, it's a bad idea, as you noted.
Ken
Arnold the Aardvark <no@way.com> wrote: [...] He's lost me a bit there. :-( 'standard argument lists'?
Me too. :)
Arnold the Aardvark
Schobi
-- Sp******@gmx.de is never read
I'm Schobi at suespammers dot org
"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Ken Alverson wrote: "Carl Daniel [VC++ MVP]" <cp************ *************** **@mvps.org.nos pam> wrote in message news:uW******** *****@TK2MSFTNG P11.phx.gbl... Ken Alverson wrote: Placement new is only designed to be used on uninitialized memory. By the time you get to the first line of a constructor, you have a semi-valid object in that memory that would be wiped out. You'll sometimes see people doing bizarre (but legal) things like:
this->~Foo(); new (this) Foo();
Is that actually legal though? I thought about it, but I wasn't sure if it was legal to call the destructor before the constructor completed.
Yes, it's legal - the object is considered constructed at the start of the
constructor body. Afterall, an exception thrown from within the constructor
body will invoke the destructor.
Either way it fails if the type of this is really a derived class and not Foo.
Indeed. Regardless of whether or not it is legal, it's a bad idea, as you noted.
Yes - it's evil. I've seen it in clever "production " code written by a
fresh young code-jockey who liked to be too clever... Ken
-cd This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Alexander Stippler |
last post by:
Hi
I have already posted and discussed the following problems once, but
despite really helpful hints I did not get any further with my problem
(I at least learned, first to exactly consider why something does not
work instead of immediately searching for work arounds) . I have the
following code resulting in an ambiguity:
--------------------------------------------------------
template <typename Impl>
class Vector {};
|
by: david |
last post by:
I have a question (not sure if just a newbie one, or a stupid one)
whose answer I couldn't find on the C# books and tutorials I could put
my hands on.
Consider the following useless class (could be a struct as well, if
you just comment out the non static parameterless constructor) and the
Main() routine :
using System;
|
by: david |
last post by:
Well, as a matter of fact I_HAD_MISSED a basic thing or two, anyway,
although Ollie's answer makes perfectly sense when dealing with
classes, it doesn't seem to me to apply as well if you have to
instantiate an array of structures; consider the following useless
code :
using System;
struct MyPointS
|
by: Bonj |
last post by:
OK I know a constructor can't have a return value but is it feasible such that I have a class whereby
//in MyClass1.
class MyClass
MyClass1(){}
~MyClass1(){}
MyClass1(int & Result) {Result = InitMyClass()}
int InitMyClass()
|
by: Bill Grigg |
last post by:
I have been successfully calling DLL's using VC++ 6.0 and also using VC++7.1
(.NET). I only mention this because I have never felt comfortable with the
process, but nonetheless it did work. Recently I started calling an unmanaged
DLL from a .NET app. It worked fine. Now I have the situation where I am
trying to call a function in one DLL from another DLL. Both are unmanaged and
are built with VC++7.1. In the calling DLL I set the property...
| |
by: Edward Diener |
last post by:
Given
value class X
{
public:
// Not allowed: X():i(100000),s(10000) { }
// Allowed
void InitializeDefaults() { i = 100000; s = 10000; }
private:
int i;
|
by: daveb |
last post by:
I'm trying to write some code that calls the constructors of STL
containers explicitly, and I can't get it to compile. A sample program
is below. One compiler complains about the last two lines (the map
constructor calls), saying that I'm trying to take the address of a
constructor. Another compiler complains about all four of the last
lines, just saying "invalid use of class". What is the correct syntax
for calling a container...
|
by: =?Utf-8?B?UVNJRGV2ZWxvcGVy?= |
last post by:
I have a C# logging assembly with a static constructor and methods that is
called from another C# Assembly that is used as a COM interface for a VB6
Application. Ideally I need to build a file name based on the name of the
VB6 application. A second choice would be a file name based on the # COM
interface assembly. I have tried calling Assembly.GetCallingAssembly() but
this fails when I use the VB6 client. Is there a way to get this...
|
by: =?Utf-8?B?TmFkYXY=?= |
last post by:
Hi,
I am trying to manually call a constructor of a template argument, the
compiler returns “error C2039: ‘T’ : is not a member...”
How can I manually call the constructor of a template argument?
Please note that I cannot use the ‘new’ operator ( as long as it allocates
memory ), see the following code snnipet as an example of what I am trying to
do.
|
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
| |
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupr who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |