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 7 1489
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
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.
Victor Bazarov <v.********@comAcast.net> wrote in news:BJCpe.81519
$N********@newsread1.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
Andre Kostur wrote: Victor Bazarov <v.********@comAcast.net> wrote in news:BJCpe.81519 $N********@newsread1.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.
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
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
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
Victor Bazarov <v.********@comAcast.net> wrote in
news:px*******************@newsread1.mlpsca01.us.t o.verio.net: Andre Kostur wrote: Victor Bazarov <v.********@comAcast.net> wrote in news:BJCpe.81519 $N********@newsread1.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.
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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.
|
by: Mark Kamoski |
last post by:
Hi--
Please help.
I need a code sample for bubble sort.
Thank you.
--Mark
|
by: Mark Kamoski |
last post by:
Hi Everyone--
Please help.
I need a code sample for merge sort.
Thank you.
--Mark
|
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...
|
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...
|
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...
|
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...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM)
The start time is equivalent to 19:00 (7PM) in Central...
|
by: erikbower65 |
last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps:
1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal.
2. Connect to...
|
by: linyimin |
last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
|
by: kcodez |
last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
|
by: Taofi |
last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same
This are my field names
ID, Budgeted, Actual, Status and Differences
...
|
by: DJRhino1175 |
last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this -
If...
|
by: DJRhino |
last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer)
If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _
310030356 Or 310030359 Or 310030362 Or...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
| | |