Consider the following code:
#include <iostream>
using namespace std;
class A{
private:
int a;
public:
A(int);
void print();
void operator =(int);
};
// One argument constructor
A::A(int b){
cout<<"Inside one argument constructor"<<endl;
this->a=b;
}
void A:: operator =(int b){
cout<<"Inside operator function"<<endl;
this->a = b;
}
void A::print(){
cout<<"Value of a ="<<a<<endl;
}
int main() {
/* INITIALIZATION */
A obj1=2;
obj1.print();
/* ASSIGNMENT */
obj1=3;
obj1.print();
return 0;
}
The output of the above code can be seen here: http://ideone.com/0hnZUb . It is:
Inside one argument constructor
Value of a =2
Inside operator function
Value of a =3
So what I have observed is that during initialization, the one-argument constructor is called but during assignment, the overloaded assignment operator function is called. Is this behavior enforced by the C++ standard, or is it compiler specific? Could anyone quote the section from the standard that defines this behavior?
This is standard behavior.
I searched in the latest C++ standard, ISO/IEC 14882:2011(E), Programming Language C++.
The following code
A obj1 = 2;
Is an initialization. It is described in section 8.5 initializers, clause 16.
16 The semantics of initializers are as follows. The destination type is the type of the object or reference being initialized and the source type is the type of the initializer expression. If the initializer is not a single (possibly parenthesized) expression, the source type is not defined.
Following part of this clause is very long. I only reference which related to your sample code.
— If the destination type is a (possibly cv-qualified) class type:
— If the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered. The applicable constructors are enumerated (13.3.1.3), and the best one is chosen through overload resolution (13.3). The constructor so selected is called to initialize the object, with the initializer expression or expression-list as its argument(s). If no constructor applies, or the overload esolution is ambiguous, the initialization is ill-formed.
Section 13.3.1.3 is Initialization by constructor.
Accroding to 8.5 and 13.3.1.3, the constructor
A(int);
is selected to initialize obj1.
As for the second one
obj1 = 3;
This behavior is defined by 5.17 Assignment and compound assignment operators, clause 4.
4 If the left operand is of class type, the class shall be complete. Assignment to objects of a class is defined by the copy/move assignment operator (12.8, 13.5.3).
13.5.3 Assignment, clause 1.
1 An assignment operator shall be implemented by a non-static member function with exactly one parameter. Because a copy assignment operator operator= is implicitly declared for a class if not declared by the user (12.8), a base class assignment operator is always hidden by the copy assignment operator of the derived class.
Function
void operator =(int);
is selected for
obj1 = 3;
according to overload rule.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With