473,549 Members | 2,948 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Strings and refs, need comments on code

Hi all,

I've been having questions about strings, references,
initializations ... I've created code (which will not compile due to a
reference problem) and I'd like comments on why this won't work and any
other comment to the code with efficiency in mind.

#include <iostream>
#include <string>

using std::cout;
using std::string;

class myClass {
public:
myClass(string s) : str(s) { }
~myClass() { }

string& getStr() const { return str; }

private:
string str;
};

int main() {

string * s = new string("FOO");
myClass * m = new myClass(*s);

cout << m->getStr() << std::endl;

delete s;
delete m;

return 0;
}

Some questions:
1 - Should constructor receive a &? (would it be faster? now, it's
copying the string in str(s), right?)
2 - why returning string& is not working? (returning just string would
return a copy of str, right?)
3 - How can I return the string, as efficiently as possible but making
sure it cannot be modified?

Any other comments are welcome.

Thanks,

Paulo Matos

Jul 23 '05 #1
7 1526
pmatos wrote:
I've been having questions about strings, references,
initializations ... I've created code (which will not compile due to a
reference problem) and I'd like comments on why this won't work and any
other comment to the code with efficiency in mind.

#include <iostream>
#include <string>

using std::cout;
using std::string;

class myClass {
public:
myClass(string s) : str(s) { }
Definitely should be

myClass(string const& s) : str(s) { }
~myClass() { }

string& getStr() const { return str; }
If your object is 'const', you can't return a non-const reference
to a member. It breaks the assumption that the object is const.

private:
string str;
};

int main() {

string * s = new string("FOO");
myClass * m = new myClass(*s);
You really shouldn't use dynamic memory unless you _have_to_. Just
plain

myClass m("FOO");

will work fine in this particular case.

cout << m->getStr() << std::endl;
If you use a local object, you'll have to change to m.getStr().

delete s;
delete m;
.... and there will be no need to delete anything.

return 0;
}

Some questions:
1 - Should constructor receive a &? (would it be faster? now, it's
copying the string in str(s), right?)
It should receive a reference, but it should still copy it locally.
As originally posted, two strings are created instead of one.
2 - why returning string& is not working? (returning just string would
return a copy of str, right?)
Right. Just return a 'string const&'.
3 - How can I return the string, as efficiently as possible but making
sure it cannot be modified?


Return by a reference to const.

V
Jul 23 '05 #2
pmatos wrote:
Hi all,

I've been having questions about strings, references,
initializations ... I've created code (which will not compile due to a
reference problem) and I'd like comments on why this won't work and any
other comment to the code with efficiency in mind.
I believe that strings generally have efficient implementations . It
does depend on your library, but they should normally have copy-on-write
reference counting, or something of that sort. I'm sure someone will
correct me if I'm wrong, but I believe that it is reasonable to pass
strings around with as little care about efficiency as if you were
passing ints or chars.
#include <iostream>
#include <string>

using std::cout;
using std::string;

class myClass {
public:
myClass(string s) : str(s) { }
~myClass() { }

string& getStr() const { return str; }

private:
string str;
};

int main() {

string * s = new string("FOO");
myClass * m = new myClass(*s);

cout << m->getStr() << std::endl;

delete s;
delete m;

return 0;
}

Some questions:
1 - Should constructor receive a &? (would it be faster? now, it's
copying the string in str(s), right?)
See above for strings. But more generally, yes, if you are passing
something like a large struct or a container you can pass it as a const
T& (const is important) and get improved efficiency.
2 - why returning string& is not working? (returning just string would
return a copy of str, right?)
Give us a clue, what is the error message?
3 - How can I return the string, as efficiently as possible but making
sure it cannot be modified?


See above for strings. But more generally, yes, this is something you
might need to worry about for large types, and it is a bit more painful
than passing parameters because you have to worry more about the
lifetime of the objects. In my code I often use "out parameters", i.e.
I require that the caller declares an (empty) variable for the result
and pass it as a reference parameter. Other options include smart
pointers. I believe that you will find some useful material in the FAQ.

--Phil.
Jul 23 '05 #3
Victor Bazarov <v.********@com Acast.net> wrote in news:BJCpe.8151 9
$N********@news read1.mlpsca01. us.to.verio.net :
pmatos wrote:
I've been having questions about strings, references,
initializations ... I've created code (which will not compile due to a
reference problem) and I'd like comments on why this won't work and any
other comment to the code with efficiency in mind.

#include <iostream>
#include <string>

using std::cout;
using std::string;

class myClass {
public:
myClass(string s) : str(s) { }


Definitely should be

myClass(string const& s) : str(s) { }
~myClass() { }

string& getStr() const { return str; }


If your object is 'const', you can't return a non-const reference
to a member. It breaks the assumption that the object is const.

private:
string str;
};

int main() {

string * s = new string("FOO");
myClass * m = new myClass(*s);


You really shouldn't use dynamic memory unless you _have_to_. Just
plain

myClass m("FOO");

will work fine in this particular case.

cout << m->getStr() << std::endl;


If you use a local object, you'll have to change to m.getStr().

delete s;
delete m;


... and there will be no need to delete anything.


You forgot to mention... and no need to delete anything in a particular
order. (OK, 'need' may be a little strong, but we'll stick with it for
now). As it is now, *m is holding a reference to *s. Between "delete s;"
and "delete m;", m is a timebomb waiting to go off. It now has a reference
to an invalid object. In a more complex program where these two delete
statements aren't next to each other, one may be tempted to try using the
*m object to access the string it references..... .

return 0;
}

Some questions:
1 - Should constructor receive a &? (would it be faster? now, it's
copying the string in str(s), right?)


It should receive a reference, but it should still copy it locally.
As originally posted, two strings are created instead of one.
2 - why returning string& is not working? (returning just string would
return a copy of str, right?)


Right. Just return a 'string const&'.
3 - How can I return the string, as efficiently as possible but making
sure it cannot be modified?


Return by a reference to const.

V


Jul 23 '05 #4
Andre Kostur wrote:
Victor Bazarov <v.********@com Acast.net> wrote in news:BJCpe.8151 9
$N********@news read1.mlpsca01. us.to.verio.net :

pmatos wrote:
I've been having questions about strings, references,
initializati ons... I've created code (which will not compile due to a
reference problem) and I'd like comments on why this won't work and any
other comment to the code with efficiency in mind.

#include <iostream>
#include <string>

using std::cout;
using std::string;

class myClass {
public:
myClass(string s) : str(s) { }
Definitely should be

myClass(string const& s) : str(s) { }

~myClass() { }

string& getStr() const { return str; }


If your object is 'const', you can't return a non-const reference
to a member. It breaks the assumption that the object is const.

private:
string str;
};

int main() {

string * s = new string("FOO");
myClass * m = new myClass(*s);


You really shouldn't use dynamic memory unless you _have_to_. Just
plain

myClass m("FOO");

will work fine in this particular case.

cout << m->getStr() << std::endl;


If you use a local object, you'll have to change to m.getStr().

delete s;
delete m;


... and there will be no need to delete anything.

You forgot to mention... and no need to delete anything in a particular
order. (OK, 'need' may be a little strong, but we'll stick with it for
now). As it is now, *m is holding a reference to *s.


Huh? '*m' is an object of class myClass, which happens to have 'str' as
its only data member, and it's not a reference...
Between "delete s;"
and "delete m;", m is a timebomb waiting to go off. It now has a reference
to an invalid object. In a more complex program where these two delete
statements aren't next to each other, one may be tempted to try using the
*m object to access the string it references..... .
You need to look at the original post again, I believe.

return 0;
}


V
Jul 23 '05 #5
Phil Endecott wrote:
pmatos wrote:
Hi all,

I've been having questions about strings, references,
initializations ... I've created code (which will not compile due to a
reference problem) and I'd like comments on why this won't work and any
other comment to the code with efficiency in mind.


I believe that strings generally have efficient implementations . It
does depend on your library, but they should normally have copy-on-write
reference counting, or something of that sort. I'm sure someone will
correct me if I'm wrong, but I believe that it is reasonable to pass
strings around with as little care about efficiency as if you were
passing ints or chars.


That may be true, but why take the chance that it isn't? See below.
#include <iostream>
#include <string>

using std::cout;
using std::string;

class myClass {
public:
myClass(string s) : str(s) { }
~myClass() { }

string& getStr() const { return str; }

private:
string str;
};

int main() {

string * s = new string("FOO");
myClass * m = new myClass(*s);

cout << m->getStr() << std::endl;

delete s;
delete m;

return 0;
}

Some questions:
1 - Should constructor receive a &? (would it be faster? now, it's
copying the string in str(s), right?)


See above for strings. But more generally, yes, if you are passing
something like a large struct or a container you can pass it as a const
T& (const is important) and get improved efficiency.


I don't think you should make an exception for std::string. The whole
point of abstraction is so you don't have to know whether or not the
class' implementation is "fast enough." Be consistent, and pass
references (to const if possible) whenever you're dealing with
*anything* other than a primitive type.
2 - why returning string& is not working? (returning just string would
return a copy of str, right?)


Give us a clue, what is the error message?


He has a const function returning a non-const reference to internal
data. That isn't allowed.
3 - How can I return the string, as efficiently as possible but making
sure it cannot be modified?


See above for strings. But more generally, yes, this is something you
might need to worry about for large types, and it is a bit more painful
than passing parameters because you have to worry more about the
lifetime of the objects. In my code I often use "out parameters", i.e.
I require that the caller declares an (empty) variable for the result
and pass it as a reference parameter. Other options include smart
pointers. I believe that you will find some useful material in the FAQ.


I think Victor's response to this was much simpler: return a reference
to const.

Kristo

Jul 23 '05 #6
pmatos wrote:
string * s = new string("FOO");
myClass * m = new myClass(*s);
Don't use 'new' without a major reason. "I need an object inside this
function" is no reason. Just construct the object directly:

string s = "FOO";
1 - Should constructor receive a &? (would it be faster? now, it's
copying the string in str(s), right?)


When starting a project, never worry about program speed. Do worry about
programmer speed. Programmers should always use the similar constructions at
similar places, just to preserve legibility. If everything else used 'const
&' and this one did not, that should raise an unanswerable question, why is
this different?

Use 'const &' because big objects need that to be fast.

--
Phlip
http://www.c2.com/cgi/wiki?ZeekLand

Jul 23 '05 #7
Victor Bazarov <v.********@com Acast.net> wrote in
news:px******** ***********@new sread1.mlpsca01 .us.to.verio.ne t:
Andre Kostur wrote:
Victor Bazarov <v.********@com Acast.net> wrote in news:BJCpe.8151 9
$N********@news read1.mlpsca01. us.to.verio.net :

pmatos wrote:

I've been having questions about strings, references,
initializat ions... I've created code (which will not compile due to
a reference problem) and I'd like comments on why this won't work
and any other comment to the code with efficiency in mind.

#include <iostream>
#include <string>

using std::cout;
using std::string;

class myClass {
public:
myClass(string s) : str(s) { }

Definitely should be

myClass(string const& s) : str(s) { }
~myClass() { }

string& getStr() const { return str; }

If your object is 'const', you can't return a non-const reference
to a member. It breaks the assumption that the object is const.
private:
string str;
};

int main() {

string * s = new string("FOO");
myClass * m = new myClass(*s);

You really shouldn't use dynamic memory unless you _have_to_. Just
plain

myClass m("FOO");

will work fine in this particular case.
cout << m->getStr() << std::endl;

If you use a local object, you'll have to change to m.getStr().
delete s;
delete m;

... and there will be no need to delete anything.

You forgot to mention... and no need to delete anything in a
particular order. (OK, 'need' may be a little strong, but we'll
stick with it for now). As it is now, *m is holding a reference to
*s.


Huh? '*m' is an object of class myClass, which happens to have 'str'
as its only data member, and it's not a reference...


Ooops.... my bad. Somehow I figured the private member was a string&.
Completely my error. Must clean my eyeballs.

I agree with your original points.... why bother to dynamically allocate
when you're (the OP) treating it as a local variable anyway.


Jul 23 '05 #8

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

Similar topics

0
1396
by: Ali | last post by:
I am in great need of code that will make a dome. I would like the inputs to be similar to that of the sphere. ie: pos=(x0, y0, z0) radius = R color = (r,g,b) etc. I am using VPython of course. Please help me.
1
8407
by: Cibulya Dmitriy | last post by:
Hi All, I want to catch the next MSSQL error in my SQL code with following continue calculations Server: Msg 17, Level 16, State 1, Line 1 SQL Server does not exist or access denied.
34
7278
by: Mark Kamoski | last post by:
Hi-- Please help. I need a code sample for bubble sort. Thank you. --Mark
2
6868
by: Mark Kamoski | last post by:
Hi Everyone-- Please help. I need a code sample for merge sort. Thank you. --Mark
1
2875
by: Riyadh Hossain | last post by:
I am developing USPS shipping API for my site. All the work is going on testing phase. My site uses PHP/MySQL. Now I am working on USPS tracking/confirm. I can send request and get responses from USPS. I need sample code for unpack XML response for USPS tracking. Sample code should be in PHP language. If it is not available in PHP, other...
0
1377
by: ravibrl | last post by:
Hey I need c++ code to access a webpage and download some software. If I execute that it should download that software and it should install it in my system. Give suggestions how to write that code or send it.
3
1577
by: dee vee bee | last post by:
this is my project i need a code that will show like this.. "first number __" "second number ___" "choose operation: addition..subtraction..multiplication..division" "the answer is ___" the user will input his number, then he will choose also what operation to use..
1
3113
by: saravanatmm | last post by:
I need javascript code for validate the email address. Email address field cannot allowed the capital letters, special characters except '@' symbol. But can allowed the small letters, numeric numbers. Now i use this script for validate the email address. But it allows the cpital letters otherwise its working correctly. SCRIPT FUNCTION ...
0
7520
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7718
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7956
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7470
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...
0
6041
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
3498
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3480
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1936
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
1
1058
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.