-
April 19th, 2004, 04:19 PM
#1
Why does this constructor-usage not compile ?
Hi,
assume a simple class like this (string-header has been included and "using namespace std" has been used):
class someclass
{
private:
string m_string;
public:
someclass(string& str){m_string = str;}
};
now I want to use this class in a programm like this
someclass* cinst = new someclass(string("test"));
but this doesn't compile without error. have you got any idea why ? the compiler-error occures at the line in the program where I want to instantiate "someclass".
if I use the following everything works fine:
string str = "test";
someclass* cinst = new someclass(str);
thank you
highhead
Last edited by highhead; April 19th, 2004 at 04:21 PM.
-
April 19th, 2004, 04:32 PM
#2
What error does the compiler give you? The syntax is correct and the following code compiles just fine:
Code:
#include <string>
using namespace std;
class someclass
{
private:
string m_string;
public:
someclass(string& str){m_string = str;}
};
int main()
{
someclass* cinst = new someclass(string("test"));
delete cinst;
return 0;
}
Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
Supports C++ and VB out of the box, but can be configured for other languages.
-
April 19th, 2004, 04:34 PM
#3
someclass(string& str){m_string = str;}
AND
someclass* cinst = new someclass(string("test"));
makes no sense.
string("test") is a temporary object, therefore keeping its reference for a new object is illegal.
**** **** **** **** **/**
-
April 19th, 2004, 04:45 PM
#4
Oh yes indeed. I saw a const in the constructor which didn't exist. Strangely enough VC6 does not complain.
Anyways, the solution is to change the constructor to:
Code:
someclass(const string& str){m_string = str;}
Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
Supports C++ and VB out of the box, but can be configured for other languages.
-
April 19th, 2004, 04:46 PM
#5
TO GUISL
Since the constructor of someclass copies the contents of the temporary variable immediately (did I mention) is copied to a internal string-instance in someclass, this is no problem.
there's NO reference kept illegally. the operator= of std::string copies the contents of the string-reference and not the reference.
-
April 19th, 2004, 04:51 PM
#6
The code that Yves posted does not compile using the Comeau compiler:
Code:
#include <string>
using namespace std;
class someclass
{
private:
string m_string;
public:
someclass(string& str){m_string = str;}
};
int main()
{
someclass* cinst = new someclass(string("test"));
delete cinst;
return 0;
}
ComeauTest.c", line 17: error: no instance of constructor "someclass::someclass"
matches the argument list
The argument types that you used are: (std::string)
someclass* cinst = new someclass(string("test"));
^
1 error detected in the compilation of "ComeauTest.c".
Regards,
Paul McKenzie
-
April 19th, 2004, 04:52 PM
#7
TO IVES
Hi Ives,
the tanslated (from my german compiler-version) error-message reads:
ERROR: "const someclass & cannot be initiallized with "string""
strange, strange....
maybe it's something with my borland-compiler.
thanks
highhead
-
April 19th, 2004, 04:54 PM
#8
Re: TO GUISL
Originally posted by highhead
there's NO reference kept illegally. the operator= of std::string copies the contents of the string-reference and not the reference.
Well, the Comeau compiler (which is one of the most stringent around, and ANSI compliant) begs to differ with your assertions.
The solution is to do this:
Code:
someclass(const std::string& str) {
m_string = str;
}
Also on a side note, you shouldn't be specifying "using namespace std" in a header file.
Regards,
Paul McKenzie
-
April 19th, 2004, 04:56 PM
#9
exactly that what Yves wanted to achieve!!
this technique is described also in Meyers's "Effevtive C++"
in order to avoid such problems with temporary objects.
The compiler is enforcing it now.
**** **** **** **** **/**
-
April 19th, 2004, 04:57 PM
#10
To Paul
I don't know and use the comeau-compiler, but it seems, that it is the same problem as with the borland-compiler I use.
strange, strange...
thanks for your report
highhead
-
April 19th, 2004, 05:00 PM
#11
Thanks to you all
The problem is, as I understood specifiying the parameter of the someclass-constructor as const. ok, I'll try it.
the time is now 0:01 here, and i'm tired.
good night and thanks again
highhead
-
April 19th, 2004, 05:02 PM
#12
Re: To Paul
Originally posted by highhead
I don't know and use the comeau-compiler, but it seems, that it is the same problem as with the borland-compiler I use.
strange, strange...
thanks for your report
highhead
I highly doubt that there is any problem.
Regards,
Paul McKenzie
-
April 19th, 2004, 05:15 PM
#13
Re: TO GUISL
Originally posted by highhead there's NO reference kept illegally. the operator= of std::string copies the contents of the string-reference and not the reference.
The argument to the constructor (string &str) would take a reference of a temporary and hence it's disallowed. You don't use that reference later, but it's still wrong.
The problem is, as I understood specifiying the parameter of the someclass-constructor as const. ok, I'll try it.
If you specify the template parameter as a const reference, then it's OK to pass temporaries into it. So make the fix I suggested above and it will be OK.
The problem lies in VC6. It should flag it as an error (at least a warning would be nice), but doesn't. Borland and Comeau are correct.
Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
Supports C++ and VB out of the box, but can be configured for other languages.
-
April 20th, 2004, 06:56 AM
#14
Thanks Ives
I did specify the parameter as const as you told and everything is in fact ok, very ok
Yes, yes... Microsoft-Compilers ...I better say nothing about them...
Thanks again
highhead
-
April 20th, 2004, 08:19 AM
#15
Yves, your point on the const, is real close, but a little off IMHO [and reading various other sources].
The problem is not that you could keep a reference to the non-const object (the temporary), for you can still do this with the temporary.
The problem is that the temporary object could be MODIFIED, but there is nop external handle to the object (it is a temporary), therefore the modifications could never be accessed outside the calling scope.
Since the usage of a non-const reference, implies that you want to change the object outside the scope of the function, the compiler stops you.
The bottom line is that all parameters pasted should be const in all cases UNLESS there is an explicit desire to modify the object. There were even some voices in the early days (circa 1992) who proposed "const" being the default for all parameters and using a "non-const" keyword!
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|