Basic knowledge
Qt/C++ constructor and explicit
1. Default constructor
A default constructor is a constructor that provides default values for all parameters, usually a no-argument constructor or a constructor that provides default values. Such as the constructors of classes Test1 and Test2
class Test1
{
public:
Test1(){} // default constructor
} ;
or
class Test2
{
public:
Test2(int i=1){} // default constructor
} ;
If you don't provide any constructor for your class, then the compiler will automatically generate a default no-argument constructor for you. Once you define a constructor for your class, even just one, the compiler will no longer generate a default constructor.
2. When you need to provide a default constructor for your class
There are many cases, listed as follows:
1. When you use a statically allocated array, and the array element type is an object of a certain class, the default constructor is called, such as the following code.
Object buffer[10]; // call default constructor
2. When you use a dynamically allocated array, and the element type of the array is an object of a certain class, you need to call the default constructor, such as the following code, if Object does not have a default constructor, it cannot be compiled, because The new operator calls the no-argument constructor of the Object class to initialize each array element.
Object* buffer = new Object[10];
3. When you use the container of the standard library, if the element type in the container is an object of a certain class, then this class needs a default constructor for the same reason as above.
vector<Object> buffer;
4. When a class A takes an object of another class B as a member, if A provides a no-argument constructor but B does not, then A cannot use its own no-argument constructor. The code below will result in a compile error.
class B
{
B(int i){}
};
class A
{
A(){}
B b;
};
int main(void)
{
A a(); // error C2512: 'B' : no appropriate default constructor available
getchar();
return 0 ;
}
Another example is the following code, class A defines a copy constructor, but does not provide a default constructor, B inherits from A, so B needs to call A's constructor to initialize A when initializing, and A has no default constructor, Therefore a compilation error occurs.
class A
{
A(const A&){}
};
class B : public A
{
};
int main(void)
{
B b; //error C2512:'B': no appropriate default constructor available
getchar();
return 0 ;
}
In addition to the above cases, there are many more, which will not be described here.
Reference from: http://www.cnblogs.com/graphics/archive/2012/10/02/2710340.html
From Qt to C++ (1): keyword explicit and implicit type conversion
ask a question
When we create a new Qt widgets application project. A framework is automatically generated, containing several files. There is a mainwindow.h header file. It is the main UI interface that you want to manipulate. Let's look at a piece of code in it:
class MainWindow : public QMainWindow
{
Q_OBJECT//A macro, not considered for the time being
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
This code defines a new class, MainWindow, that inherits from QMainWindow. We can see that in its constructor, there is a keyword explicit in front. I believe everyone is familiar with constructors without this keyword. So what does this explicit do?
explicit research
explicit is a keyword in C++, not in C language. The English literal translation means "clear" and "explicit". The reason for the appearance of this keyword is based on the following provisions in C++: When a constructor with only one parameter is defined, an implicit type conversion is also defined. Look at type conversion first.
type conversion
In C/C++, there are many type conversions. for example:
double a = 12.34;
int b = (int)a;
We all know that the value of b is 12 at this time. By adding the type wrapped in parentheses in front of the variable, explicit type conversion can be achieved. This is called coercion. It's worth mentioning, by the way, that C++ also supports an example of this type of cast:
double a = 12.34;
int b = int(a);
In addition to this, there is another type of conversion called implicit type conversion.
double a = 12.34;
int b = a;
Similarly, the value of b is also 12. Although there is no explicit conversion type, the compiler will automatically convert it for you. Similarly, not only the basic data types, but also the conversion relationship between the self-defined classes and objects.
Implicitly Converted Scenarios
Equals and Constructors
Say you have an object of class A:
class A
{
public:
A(int i)
{
a = i;
}
int getValue()
{
return a;
};
private:
int a;
};
You will find that in the main function, it is legal to use the following statement:
A a = 10;
The reason why an object of class A can be initialized directly with an integer using the equal sign is because this statement calls the default single-argument constructor, which is equivalent to A temp(10); a(temp);
First the compiler executes A temp(10); creates a temporary object (assuming it is called temp) on the stack. Then call the copy initialization constructor a(temp) of object a to initialize a. Then the temporary object temp is destroyed. That's the implicit conversion work that the compiler does. You can think that the result of such an implicit operation is the same as the result of calling A a(10); directly, but the implicit conversion will be more expensive because of the use of the copy constructor. Of course, this basic data type may not be obvious. If a complex object, such as a Qt window. So the cost can be imagined.
Another example will fail when you use the following statement:
A a = "123";
Because there is no single-argument constructor whose argument is a string. Knowing this, you can modify it to pass.
class A
{
public:
A(int i)
{
a = i;
}
A(char * c)
{
a=c[0];
}
int getValue()
{
return a;
};
private:
int a;
};
function call
We define a function print to print the value of the A object.
void print(A a)
{
cout<<a.getValue();
};
In the main function:
void main()
{
print(10);
}
This can be compiled and run. Although we did not create an object of class A to pass to the print function. But the compiler will call the single-argument constructor of class A by default to create an object of class A.
plus explicit
As you can see above, the compiler will do some implicit type conversion work for you. This may be convenient for you, but sometimes it can be a hassle. Let's make an assumption:
The above class A, only accepts integer and string types. So you want to pass a string "2" as a parameter to construct a new object. For example, A b = "2"; However, you made a mistake. Double quotes are written as single quotes and become A b = '2'; However, this will not report an error. The compiler will cast the character '2' to an integer which is its ascll code - 50. To avoid this implicit conversion we don't want, we can add the explicit keyword.
public:
explicit A(int i)
{
a=i;
}
In this way, implicit type conversion can be avoided, and an error will be reported when you write a single quote by mistake. This allows only explicit calls to single-argument constructors. Such as A a(10); A b("123");
Not only that, after adding explicit, the print function will also report an error. Because the compiler will not actively call the constructor identified by explicit. This requires you to display it yourself to call:
print(A(10));
Of course, whether implicit conversions should be prohibited is inconclusive, there is no one-size-fits-all standard, and it depends on your situation.
In general, calling the constructor explicitly saves the trouble of letting the programmer manage it manually. Many people say that C++ is difficult because many things are not transparent to programmers, such as memory release. This explicit call also requires programmers to do it themselves. However, I feel that this is the charm of C++. C++ gives programmers almost the same power as God, and everything can be controlled by themselves, such as the power of operator overloading, and even the ability to customize slot and signal keywords like Qt ( Actually macros), which is unthinkable in other high-level languages. Of course, language is something that the benevolent sees the benevolent and the wise sees the wisdom. There is no need to argue about pros and cons. What I have always believed is: there is no best language, only the most suitable language. There is no good or bad programming language itself, but different programmers do have different likes and dislikes for different languages.
explicit usage precautions:
* The explicit keyword can only be used on constructor declarations inside a class.
* The explicit keyword applies to single-argument constructors (or multi-argument constructors that have default values for all but the first argument), such as Circle(int x, int y = 0).
* In C++, the explicit keyword is used to modify the constructor of a class. The class of the modified constructor cannot perform the corresponding implicit type conversion, and can only perform type conversion in an explicit way.
Incidentally
The explicit keyword is only used in class declarations. The external implementation part does not need to be used.
#include<iostream>
using namespace std;
class A
{
public:
explicit A(int i);
A(char * c)
{
a=c[0];
}
int getValue()
{
return a;
};
private:
int a;
};
A::A(int i)//No need to specify explicit
{
a=i;
}
void print(A a)
{
cout<<a.getValue();
};
void main()
{
print(A(10));
}
Reprinted from: http://blog.csdn.net/guodongxiaren/article/details/24455653?utm_source=tuicool&utm_medium=referral