Click here to Skip to main content
15,894,106 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
The code:
C++
#include <iostream>
using namespace std;

class String
{

	char name[256];
public:

	String(char* str)
	{
		cout<<"Constructor" << endl;
		strcpy(name,str);
	}

	String(String &s)
	{
		cout<< "Copy Constructor"<< endl;
		strcpy(name,s.name);
	}

	String()
	{
		cout<<"Default Constructor"<<endl;
	}

	~String(){}

	String& operator=(const String&s)
	{
		strcpy(name,s.name);
		cout<<"Assign Operator"<<endl;
		return *this;
	}


	void display()
	{
		cout << "The String is:" << name << endl;
	}
};


int main()
{
	String mystr1 = "a";//Why does it only print "Constructor"?
	String mystr2;
	mystr2 = "aa";
	String mystr3("aaa");//Here just invoke String::String(char *str).
	return 0;
}


Why don't invoke String::String(String &s) while defining "mystr1" ? How compiler deals with the mystr1 definition?
Posted

Your code only requires the default constructors as you are passing char*s as intialisation parameters. You need to pass objects to get the copy constructor and =op to be invoked. Try this:
C++
String mystr2;
mystr2 = mystr1;
String mystr3(mystr2);
 
Share this answer
 
Comments
Bo Ye 14-Jan-12 7:08am    
You misunderstand what I mean. This is my test code, mystr1 has no relationship with mystr2. I just would like to know how the compiler deals with the sigle sentence String mystr1 = "a";
Richard MacCutchan 14-Jan-12 7:15am    
No, I think you misunderstand. The statement String mystr1 = "a"; calls the first constructor of your class. You are asking why it does not call the copy constructor or the assignment operator and I gave you some sample code to demonstrate it. Give it a try and see what happens, or better still, step through the code with your debugger and you will see each statement in turn.
Bo Ye 14-Jan-12 7:26am    
ah... I know it doen't call the assignment constructor. I just wanna figure it out why it seemed that the copy constructor is not called.
Richard MacCutchan 14-Jan-12 7:33am    
Because there is nothing to copy, you are passing an Rvalue to the constructor. Try the code that I suggested and you will see how (and when) it does get called.
Bo Ye 14-Jan-12 7:32am    
I rewrite the main function:
int main()
{
String mystr1 = "a";//Why does it only print "Constructor"?
String mystr3("aaa");//Here just invoke String::String(char *str).
return 0;
}
mystr1 is constructed without parameter. So the default constructor String() is called. Additionally, there is no copy operation defined for char* You may add this:
C++
String& operator=(const char* s)
{
    ASSERT(s);
    strncpy(name, s, 256);
    name[255] = '\0';
    cout<<"char* assign Operator"<<endl;
    return *this;
    }


Edit:
CPallini is right and my answer is wrong.
 
Share this answer
 
v2
Comments
Ashish Tyagi 40 14-Jan-12 9:49am    
Exactly right, my 5.
Constructors are implicit converters,

C++
String mystr1 = "a";//Why does it only print "Constructor"?
     
is as good as (if you are using non explicit constructor taking char*)

String mystr1("a");//Why does it only print "Constructor"?

C++
 use explicit keyword and then try -


....
explicit String(char* str)
	{
		cout<<"Constructor" << endl;
		strcpy(name,str);
	}
....
String mystr1 = "a";// This won't compile now
                   // and no implicit conversions will take place. 


This link will also help.
 
Share this answer
 
v3
Comments
Richard MacCutchan 14-Jan-12 9:37am    
And a 5 for that, I forgot about the new keyword(s).
Ashish Tyagi 40 14-Jan-12 9:39am    
:-)
Bo Ye 16-Jan-12 8:30am    
No, "String mystr1 = "a";" is initialization, not assignment. operator=(const char*) is not called.
Ashish Tyagi 40 16-Jan-12 11:32am    
Yes you are correct, I update my answer accordingly.
OK, I think I see where you may be confused.
C++
String mystr1 = "a";

In this case the compiler can optimise the statement to an existing constructor (String(char* str)), because the creation and assignment happen together.

C++
String mystr2;
mystr2 = "aa";

In this case the creation of the String object does not have any initialiser so the default constructor is called. On the next line a value ("aa") is to be assigned to mystr2, and the way to do that is to construct a temporary String object (using an appropriate constructor), and then use the assignment operator to set the value of the previously created one (mystr2). It could be argued that the compiler should optimise this to the same as case 1, as the two operations are in sequence.

C++
String mystr3("aaa");

In this case the code is a constructor call so the constructor that takes a char* will be called.

C++
String mystr3(mystr2);

In this case the parameter is a String object so the compiler will generate a call to the copy constructor.
 
Share this answer
 
Comments
Ashish Tyagi 40 14-Jan-12 9:28am    
Good one Richard, my 5.
Emilio Garavaglia 14-Jan-12 13:53pm    
"In this case the compiler can optimise the statement to an existing constructor (String(char* str)), because the creation and assignment happen together."

That's not corect: the standard REQUIRES that the = after a declaration introduce an initialization, hence it is not an assignment.
It is not something the compiler CAN do. The compiler MUST do that way.
Richard MacCutchan 15-Jan-12 3:21am    
Thanks, I should have checked the standard first, and will do as soon as time permits.
Bo Ye 15-Jan-12 3:37am    
Very specific. Thank you all very much.
Bo Ye wrote:
String mystr1 = "a";//Why does it only print "Constructor"?


The compiler short-cuts the passage of temporary object creation, i.e. instead of producing
C++
String mystr1 = String("a");


it generates
C++
String mystr1("a");


[update]
I used at least improper terminology in my answer, please see Emilio's remark.
[/update]
 
Share this answer
 
v2
Comments
Bo Ye 14-Jan-12 7:13am    
Is all compilers so do? like gcc or others?
CPallini 14-Jan-12 10:20am    
All the ones I used (yes, gcc is one of them).
Emilio Garavaglia 14-Jan-12 13:50pm    
Carlo, it is not an optimization: the standard explicitly says that the = after a declaration is "initialization", not "assignment", and hence the constructor is called. It is not "creating an empty string and then change it by give it an 'a', but "create a string that 'is like an' 'a' ".
CPallini 14-Jan-12 16:46pm    
Yes, you are right. Thank you for pointing out.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900