I had this exercise during my lecture, The answer are in the comments,
I had 2 which I did not understand, and the question is showed in the comment.
1 2 3 4 5 6 7 8 9 10
int main () {
String s0(“abc”); //C'tor-Why not copy C'tor?
String s1 = s0; //copy C'tor
String s2(s0); //copy C'tor
String s3=“abc”; //copy C'tor, why not just a C'tor? I was told during the lecture
//that this is a char* and a copy C'tor gets string only.
//So how come I see the diffrence between the string and a char*?
String s4; //
s4 = s3;
return 1; }
The copy ctor is called when one object gets copied to another object.
Example: String s1 = s0;
This is the copy ctor because 's0' is a String object, and it is being copied to 's1'.
On the other hand... String s0(“abc”);
This is NOT the copy ctor because "abc" is not a String object... and therefore this is not an object->object copy... but instead it is constructing an object from a string literal. So this is calling the ctor which takes a const char* as a parameter.
String s3=“abc”; //copy C'tor, why not just a C'tor?
This is NOT the copy ctor, for the same reason the above was not a copy ctor. The correct answer here is the 'normal' const char* ctor.
The normal order of calling constructors in the following line
String s3=“abc”;
is the following. At first the constructor with the first parameter of const char * is called. It creates a temporary object of type String. When the move (if defined) or copy constructor is called to create named object s3 from this temporary object. So in fact two constructors, one with a parameter and the second either the move constructor or the copy constructor, are called.
However the C++ Standard allows to eliminate the call of the move or copy constructor Nevertheless the copy or move constructor shall be acceptable.
This code shall not be compiled (except that MS VC++ 2010 contains a bug and will compile this code:) ) because the copy constructor is inaccessible though it wouldl not be called if it were public.
As you said, in this code-line we are calling 2 constructors:
1)The first C'tor which convert this char* to a string(what is the name of this C'tor?)
2)a copy C'tor to copy this converted string to s3(why are we now calling op= ??)
Last thing,
I do not understand how to implement a copy C'tor, can anyone give me an example?
I described all detailed. try the example I showed that is make the copy constructer private and the code will not be compiled. Or another example declare the copy constructor explicit and again the code will not be compiled.
I can't try it now as the only compiler I have here is VS (which you already said it works on), but I would be very surprised if that were actually the case.
I had always been under the impression that String a = "foo"; and String a("foo"); were identical apart from the latter being explicit.
If you're right this draws into question this example:
1 2 3 4 5 6 7 8
void func( const String& a )
{
...
}
int main()
{
func( "foo "); // by your rationale, wouldn't this also call the copy ctor?
This seems insane and wasteful to me... and I find it very hard to believe the standard dictates this. There is literally no reason for the temporary to be created in either case here.
> by your rationale, wouldn't this also call the copy ctor?
> This seems insane and wasteful to me... and I find it very hard to believe the standard dictates this.
It involves copy initialization (not copy construction).
> and am completely flabbergasted.
> That makes zero sense to me.
Copy initialization is less permissive than direct initialization. That does not imply that it must be any less efficient than direct initialization.
In the above example, if there is no accessible non-explicit constructor, there would be a compile-time error. If there is one, there is no error, and the code generated is the same as in the case of direct initialization (the copy constructor is required to be accessible even though it's not used).
In the general sense of the word "string", it's a string. A char* is the basic way to handle strings in C. "abc" is a string literal, so therefore it's a char*.
But it's not a std::string. std::string is the STL string class. It's different from a char*, and is much more powerful (and safer) to use.
In C and C++, a string literal has the type char*, not std::string.
Edit: and I have no idea what the String type is that you have in your code, but I presume it's another class that implements a string, and so is different again from both std::string and char*.