- Class should typically define a default constructor
To sample cases where a default constructor is required, assume that there is a NoDefault class that does not define its own default constructor, but has a constructor that accepts a string argument.
There is no mistake in defining such a class, so the compilation succeeds:
ClassNoDefault {Public:voidOutput () {cout << units_sold <<Endl } nodefault (CONST STD::String &Book): ISBN (Book), Units_sold (0), Revenue (0.0) {cout <<"First constructor"<< Endl;} / *nodefault (): Units_sold (0), Revenue (0.0) {cout << "second constructor" << Endl;} */private: std::string ISBN; unsigned units_sold; double revenue;}; int Main () {System ("pause"); return 0;}
However, if you define an object, you will get an error:
Because the class defines a constructor, the compiler will not synthesize the default constructor. NoDefault does not have a default constructor, which means:
(1) Each constructor for each class that has a nodefault member must be explicitly initialized by passing an initial string value to the NoDefault constructor NoDefault members .
If NoDefault has a default constructor:
classNoDefault { Public: NoDefault (ConstSTD::stringBook ): ISBN (Book), Units_sold (0), Revenue (0.0) {cout<<"NoDefault Constructor"<<Endl; } nodefault (): Units_sold (0), Revenue (0.0) {cout<<"NoDefault Default constructor"<<Endl; }Private: std::stringISBN; unsigned units_sold; Doublerevenue;};classSales_item { Public: DoubleAvg_price ()Const; BOOLSAME_ISBN (ConstSales_item &RHS)Const { returnISBN = =RHS.ISBN; } voidoutput () {cout<< Units_sold <<Endl; } sales_item (ConstSTD::string&Book ): ISBN (Book), Units_sold (0), Revenue (0.0) {cout<<"Sales_item Constructor"<<Endl; } sales_item (): Units_sold (0), Revenue (0.0) {cout<<"Sales_item Default constructor"<<Endl; }Private: std::stringISBN; NoDefault ND; unsigned units_sold; Doublerevenue;};intMain () {Sales_item si; System ("Pause"); return 0;}
Output Result:
If NoDefault does not have a default constructor:
Output Result:
(2) The compiler will not synthesize a default constructor for a class that has a nodefault type member. If such a class wants to provide a default constructor, it must be explicitly defined, and the default constructor must explicitly initialize its nodefault member (as in the previous example) to expect the compiler to be Sales_item The composition default constructor will error:
classNoDefault { Public: NoDefault (ConstSTD::stringBook ): ISBN (Book), Units_sold (0), Revenue (0.0) {cout<<"NoDefault Constructor"<<Endl; }Private: std::stringISBN; unsigned units_sold; Doublerevenue;};classSales_item { Public: DoubleAvg_price ()Const; BOOLSAME_ISBN (ConstSales_item &RHS)Const { returnISBN = =RHS.ISBN; } voidoutput () {cout<< Units_sold <<Endl; }Private: std::stringISBN; NoDefault ND; unsigned units_sold; Doublerevenue;};intMain () {Sales_item si; System ("Pause"); return 0;}
Error:
If there is no nodefault as a member of the Sales_item, the compilation succeeds.
(3) statically allocated array of type NoDefault must provide an explicit initialization for each element
Output Result:
If the NoDefault does not have a default constructor, an error is added:
This array also cannot pass the initial value to the members of each nodefault type.
(4) Statically allocated arrays of typeNoDefault must provide an explicit initialization for each element.
Otherwise the error will still be:
(5) If you have a container that holds a NoDefault object, such as a vector, you cannot use a constructor that accepts a container size without providing an element initializer at the same time
in fact, if other constructors are defined, it is almost always right to provide a default constructor. In general, the initial value given to a member in the default constructor should indicate that the object is "empty" .
Use the default constructor to define the correct method for an object:
// Ok:defines A Class object ... Sales_item myobj;
If it is defined as:
Sales_item myobj (); // Ok:but defines a function, not an object
The definition of myobj is interpreted by the compiler as a declaration of a function that does not accept arguments and returns an object of type Sales_item .
The definition is also correct:
// ok:create an unnamed, empty sales_itemand use to initialize myobj Sales_item myobj = Sales_item ();
We create and initialize a Sales_item object, and then use it to initialize myobjby value. The compiler initializes a Sales_itemby value by running the default constructor for Sales_item .
- Implicit class-Type conversions
the C + + language defines several automatic transformations between built-in types. You can also define how to implicitly convert objects of other types to our class types, or implicitly convert objects of our class type to other types. In order to define an implicit conversion to a class type, you need to define the appropriate constructor. A constructor that can be called with a single argument defines an implicit conversion from the formal parameter type to the class type .
Let's take a look at the Sales_item version that defines the two constructors:
class Sales_item { public: // default argument for book is the empty string
Sales_item (const std::string""): ISBN (book), Units_sold ( 0), Revenue (0.0) {} &is); // As before };
There is a member function in this class
The bool SAME_ISBN (constconst/Constmember cannot change the data member of the object it is manipulating. return ISBN = = rhs.isbn;}
When using this member function as follows, each of these constructors defines an implicit conversion :
string " 9-999-99999-9 " ; // Ok:builds a sales_itemwith 0 units_soldand revenue from // and ISBN equal to Null_book ITEM.SAME_ISBN (null_book);
Therefore, a string or a istreamcan be used where a sales_item type object is expected.
If you do not have these two constructors, you will get an error:
Class (Medium)