473,507 Members | 2,387 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Concatenating Calls

i am fresher to C++ programming, and I just
want to learn Concatenating Calls, I have
written a program,
class SetMe {
public:
void setX(int x) {_x = x;}
void setY(int y) {_y = y;}
void doubleMe()
{
_x *= 2;
_y *= 2;
}
private:
int _x;
int _y;
};
int main(){
SetMe lower;
((lower.setX(20)).setY(30)).doubleMe();
}
While compiling on gcc version 3.2.3 on Redhat Linux
it gives following errors,
point.c: In function `int main()':
point.c:17: request for member `setY' in
`(&lower)->SetMe::setX(int)(20)', which is of non-aggregate type
`void'
Would somebody explain how to remove this error.
I want to retain the style of concatenating calls

thanks
divya

Jul 23 '05 #1
14 1731
foodic wrote:
i am fresher to C++ programming, and I just
want to learn Concatenating Calls, I have
written a program,
class SetMe {
public:
void setX(int x) {_x = x;}
setX returns void !
void setY(int y) {_y = y;}
So does setY.
void doubleMe()
{
_x *= 2;
_y *= 2;
}
private:
int _x;
int _y;
};
int main(){
SetMe lower;
((lower.setX(20)).setY(30)).doubleMe();
Here you use the return value from setX (which is void) and call setY.
You probably want to do this.

SetMe & setX(int x) {_x = x; return *this;}
SetMe & setY(int y) {_y = y; return *this;}
SetMe * doubleMe() { .... return *this;}
}
While compiling on gcc version 3.2.3 on Redhat Linux
it gives following errors,
point.c: In function `int main()':
point.c:17: request for member `setY' in
`(&lower)->SetMe::setX(int)(20)', which is of non-aggregate type
`void'
Would somebody explain how to remove this error.
I want to retain the style of concatenating calls


Return the object by reference.
Jul 23 '05 #2
foodic wrote:

i am fresher to C++ programming, and I just
want to learn Concatenating Calls, I have
written a program,

class SetMe {
public:
void setX(int x) {_x = x;}
void setY(int y) {_y = y;}
void doubleMe()
{
_x *= 2;
_y *= 2;
}
private:
int _x;
int _y;
};
int main(){
SetMe lower;
((lower.setX(20)).setY(30)).doubleMe();
}
While compiling on gcc version 3.2.3 on Redhat Linux
it gives following errors,
point.c: In function `int main()':
point.c:17: request for member `setY' in
`(&lower)->SetMe::setX(int)(20)', which is of non-aggregate type
`void'
Would somebody explain how to remove this error.
I want to retain the style of concatenating calls


The keypoint in this is, that each function has to return something
that the next call can act on.

If you want to do

SetMe lower;

lower.setX( 20 ).setY(30);

then the part

lower.setX( 20 )

must evaluate to something that is usable as object such
that setY can work on. Best you start with

SetMe lower;

SetMe someObj;
someObj.setY( 30 );

now replace someObj with lower.setX( 20 )

lower.setX( 20 ).setY( 20 );

from this it is clear that the expression "lower.SetX( 20 )" must
have the same type as someObj before. Thus SetX must return a SetMe
object. (For obvious reasons I do the same modification on SetX,
SetY and doubleMe simultanously)

(Note: the following is not quite what you want, but close.
I come back to it in a minute)

class SetMe
{
public:
SetMe setX(int x) { _x = x; return *this; }
SetMe setY(int y) { _y = y; return *this; }

SetMe doubleMe()
{
_x *= 2;
_y *= 2;

return *this;
}

private:
int _x;
int _y;
};

Now every function returns a SetMe object. Thus when
lower.SetX( 20 )
is evaluated, its result is a SetMe object, which can be
used for the next call:

lower.setX( 20 ).doubleMe().setY( 30 );

But wait: What is the exact return type of each function?
It is 'SetMe'. That means that for every return a copy
of the object that was worked on is returned. Thus in the
above the object for which doubleMe is called, is *not*
lower, but is an object which is an exact copy of lower right
after the call to SetX has finished. If this is not what you
want, then the return type needs some slight modification.
What we want is not a copy of the object, but the object itself.
We do this by returning a reference to the object:

class SetMe
{
public:
SetMe& setX(int x) { _x = x; return *this; }
SetMe& setY(int y) { _y = y; return *this; }

SetMe& doubleMe()
{
_x *= 2;
_y *= 2;

return *this;
}

private:
int _x;
int _y;
};

Now the returned object of setX is the very same object that
was used for the call to setX ( 'this' is the C++ way to say
'I' or 'me'. The only thing is that 'this' is a pointer type.
So to say 'return me' you have to dereference the pointer, hence
return *this; )

In

lower.setX( 20 ).setY( 30 );

the call to setX now returns a reference to the object it was
called with, which was 'lower'. Thus setY will again work on 'lower'
and do its work.

That's the whole secret.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #3

"Karl Heinz Buchegger" <kb******@gascad.at>, haber iletisinde sunlari
yazdi:42***************@gascad.at...

<snip>

lower.setX( 20 ).setY( 30 );
You can even begin with the class contructor like this:

SetMe().setX( 20 ).setY( 30 );
// if you don't need "lower" after this line of course,
// say passing it finally into a function as a parameter.
the call to setX now returns a reference to the object it was
called with, which was 'lower'. Thus setY will again work on 'lower'
and do its work.

That's the whole secret.

--
Karl Heinz Buchegger
kb******@gascad.at

Jul 23 '05 #4
Aslan Kral wrote:
You can even begin with the class contructor like this:

SetMe().setX( 20 ).setY( 30 );


That's not a constructor. You can't call constructors nor do
they return a value.

Jul 23 '05 #5

"Ron Natalie" <ro*@sensor.com>, haber iletisinde sunlari
yazdi:42**********************@news.newshosting.co m...
Aslan Kral wrote:
You can even begin with the class contructor like this:

SetMe().setX( 20 ).setY( 30 );


That's not a constructor. You can't call constructors nor do
they return a value.

What do you call it then? And how does it work on my pc? (See beloew)

class SetMe {
public:
SetMe()
{
printf("SetMe constructor\n");
}
SetMe& setX(int x) {_x = x; return *this; }
SetMe& setY(int y) {_y = y; return *this; }
SetMe& doubleMe()
{
_x *= 2;
_y *= 2;
return *this;
}
private:
int _x;
int _y;
};

int main()
{
printf("Before -- SetMe constructor\n");
SetMe().setX(1).setY(2);
printf("After -- SetMe constructor\n");
return 0;
}

Output:
Before -- SetMe constructor
SetMe constructor
After -- SetMe constructor
Jul 23 '05 #6
Ron Natalie wrote:
That's not a constructor. You can't call constructors
I can call constructors, although indirectly. Look at this:

---------->8---------->8----------
class Foo
{
Foo(int) {}
};

int main()
{
Foo(10); // constructor call
}
---------->8---------->8----------
nor do they return a value.


ISO-IEC 14882-1998 §12.1.12:

"No return type (not even void) shall be specified for a constructor. A
return statement in the body of a constructor shall not specify a return
value. The address of a constructor shall not be taken."

There is not written that a constructor doesn't have a return type.
Please correct me if it's written at another place.

Jul 23 '05 #7

"Michael Etscheid" <th***********@gmail.com> wrote in message
news:d0*************@news.t-online.com...
Ron Natalie wrote:
That's not a constructor. You can't call constructors


I can call constructors, although indirectly. Look at this:

---------->8---------->8----------
class Foo
{
Foo(int) {}
};

int main()
{
Foo(10); // constructor call
}
---------->8---------->8----------
> nor do they return a value.


ISO-IEC 14882-1998 '12.1.12:

"No return type (not even void) shall be specified for a constructor. A
return statement in the body of a constructor shall not specify a return
value. The address of a constructor shall not be taken."

There is not written that a constructor doesn't have a return type. Please
correct me if it's written at another place.


It looks like it says there is no return type pretty clearly, at least to
me. It says "No return type..shall be specified". That means that it does
not have a return type. How can you have a return type if you don't specify
what the type _is_? It also says it "shall not specify a return value".
That means that nothing _can_ be returned! In other words, if you have a
return statement in the constructor, it hsa to stand alone, as in "return;",
instead of specifying a return value as in "return 0;". So, if a
constructor does not specify a return type, and does not return a value, how
can you say it "has" a return type? I'd like to see an example of a
constructor that _does_ have a return type!

By the way, your example does not actually "call" the constructor. When you
write the statement "Foo(10);", you're creating an unnamed temporary
variable. The creation of that temporary does involve calling that
constructor, but technically you're not doing so yourself. (Which, I
suppose, is why you stated "although indirectly" above.)

-Howard

Jul 23 '05 #8
Michael Etscheid wrote:
Foo(10); // constructor call
correct me if it's written at another place.


That's not a constructor call. Constructors don't have names,
they don't participate in name look up. The syntax you have above
is actually an "explicit conversion (functional notation)" according
to the language syntax.

What it does is convert 10 to type Foo (creating a temporary in
the process). The creation of this temporary involves allocation
of sizeof (FOO) bytes of memory and then initializing it by calling
the Foo(int) constructor.

It's impossible for user code to call constructors, they can only
create objects in ways that the implmentation invokes the constructors
for them.
Jul 23 '05 #9
Ron Natalie wrote:
Michael Etscheid wrote: ....

It's impossible for user code to call constructors, they can only
create objects in ways that the implmentation invokes the constructors
for them.


Except for placement new. This is essentially a constructor call (not
in the strict C++ sense).
Jul 23 '05 #10
Ron Natalie schrieb:
That's not a constructor call. [...] and then initializing it by calling
the Foo(int) constructor.

It's impossible for user code to call constructors, they can only
create objects in ways that the implmentation invokes the constructors
for them.


That's why I wrote indirectly.
Jul 23 '05 #11
Howard wrote:
It looks like it says there is no return type pretty clearly, at least to
me. It says "No return type..shall be specified". That means that it does
not have a return type. How can you have a return type if you don't specify
what the type _is_? It also says it "shall not specify a return value".
That means that nothing _can_ be returned!
Or it says that the return type is specified and unchangable. I don't
know that with that text.
By the way, your example does not actually "call" the constructor. When you
write the statement "Foo(10);", you're creating an unnamed temporary
variable. The creation of that temporary does involve calling that
constructor, but technically you're not doing so yourself. (Which, I
suppose, is why you stated "although indirectly" above.)


Right.
Jul 23 '05 #12
Aslan Kral wrote:

"Karl Heinz Buchegger" <kb******@gascad.at>, haber iletisinde sunlari
yazdi:42***************@gascad.at...
Aslan Kral wrote:

"Ron Natalie" <ro*@sensor.com>, haber iletisinde sunlari
yazdi:42**********************@news.newshosting.co m...
> Aslan Kral wrote:
>
> > You can even begin with the class contructor like this:
> >
> > SetMe().setX( 20 ).setY( 30 );
>
> That's not a constructor. You can't call constructors nor do
> they return a value.
>
What do you call it then?


Creation of a temporary object

And calling the constructor as a result. Does it matter to call it John or
Mary?


Yes, it does.

The C++ programmer cannot directly call a constructor (for good reasons).
The constructor is no ordinary function, it doesn't participate in function
name lookup. Thus it is impossible to call it.

But one can create an object in various ways. Part of that object construction
is that the constructor gets called. That's a subtle different thing and answers
a question that comes up frequently: "How can I call a constructor from inside
another constructor? Why doesn't it work the way I do it?"

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #13

"Karl Heinz Buchegger" <kb******@gascad.at>, haber iletisinde sunlari
yazdi:42***************@gascad.at...
Aslan Kral wrote:

"Karl Heinz Buchegger" <kb******@gascad.at>, haber iletisinde sunlari
yazdi:42***************@gascad.at...
Aslan Kral wrote:
>
> "Ron Natalie" <ro*@sensor.com>, haber iletisinde sunlari
> yazdi:42**********************@news.newshosting.co m...
> > Aslan Kral wrote:
> >
> > > You can even begin with the class contructor like this:
> > >
> > > SetMe().setX( 20 ).setY( 30 );
> >
> > That's not a constructor. You can't call constructors nor do
> > they return a value.
> >
> What do you call it then?

Creation of a temporary object And calling the constructor as a result. Does it matter to call it John or Mary?


Yes, it does.

The C++ programmer cannot directly call a constructor (for good reasons).
The constructor is no ordinary function, it doesn't participate in

function name lookup. Thus it is impossible to call it.

I didn't say you can call a constructor directly. I should have said
"indirectly" which I didn't and you assumed I meant "directly".

My point was to show that entire program could just be one line as an
example of "Concatenating Calls" starting with object creation at the
beginning (so constructor called *indirectly*).

class X
{
int i;
public:
X(int i_){ i=i_; }
X& M1(int i) { ++i; return *this; }
int M2(int i) { return --i; }
};

int main()
{
return X(1).M1(2).M2(3);
}

But one can create an object in various ways. Part of that object construction is that the constructor gets called. That's a subtle different thing and answers a question that comes up frequently: "How can I call a constructor from inside another constructor? Why doesn't it work the way I do it?"

--
Karl Heinz Buchegger
kb******@gascad.at

Jul 23 '05 #14
Aslan Kral wrote:


I didn't say you can call a constructor directly. I should have said
"indirectly" which I didn't and you assumed I meant "directly".
I think all of the regulars understood what you ment.
Nevertheless, all I can say is: Watch your language!
We are mostly dealing with newbies, so using a proper
nomenclature is important.
My point was to show that entire program could just be one line as an
example of "Concatenating Calls" starting with object creation at the
beginning (so constructor called *indirectly*).


So why didn't you say so in the beginning:

You can even begin with creating a temporary object like so:
SetMe().setX( 20 ).setY( 30 );

and nobody would have objected to anything.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #15

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

Similar topics

1
2038
by: dont bother | last post by:
Hey, I have these attributes: index which is a numerical value value vector which is a numerical float value and I want to concatenate like this:
6
2260
by: nwheavyw8 | last post by:
I am currently trying to write a simple PHP script that will split an uploading file up into 500kb "chunks", then read and concatenate them back together when accessed for download. I can't seem...
16
3037
by: Dixie | last post by:
I have a problem using Dev Ashish's excellent module to concatenate the results of a field from several records into one record. I am using the code to concatenate certain awards onto a...
4
2319
by: Juan | last post by:
Does any one know if there are reported bugs when concatenating strings? When debugging each variable has the correct value but when I try to concatenate them some values are missing (I can´t see...
1
3666
by: ebobnar | last post by:
I need to call the function LoadImage which take a LPCTSTR argument to specify the path to the image to load. However, I need to create this path dynamically from user input by concatenating...
1
1213
by: Ani | last post by:
I have a questionaire page , which basically has questions with multiple choice answers. I need to accomplish paging on this and there are few questions that are gender specific. According the...
0
4816
by: Big D | last post by:
Hey there. I'd like to concatenate multiple wav files together. I've got an almost completely working system for it, actually... I'm using AudioSystem.write and my own subclass of...
7
2761
by: Mary | last post by:
I have a student who has a hyphenated first name. If I concatenate the name like this: StudentName:( & ", " & ), it works as expected. If, however, I try to get the first name first by...
5
3724
by: JRNewKid | last post by:
I want to concatenate two fields on a report. They are two text fields, wrkDescription is 10 characters long and wrkTextDescription is 255. I have them concatenated in the report but I'm only...
0
7111
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
7319
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,...
1
7031
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...
0
7485
tracyyun
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...
0
5623
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5042
isladogs
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...
0
3191
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1542
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 ...
0
412
bsmnconsultancy
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...

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.