C++ only stipulates constructors. init() needs to be declared only when the C++ user feels it is appropriate. It does not mean that every C++ class needs to have a init().
Generally speaking, the constructor should only be used to initialize member variables, and additional initialization functions should be used for initialization related to business logic, especially business code that contains error branches.
This is stipulated because the constructor has many restrictions. For example, it cannot return an error code to indicate an error, and it should not throw an exception (because doing so will cause the destructor to not be executed, which often causes problems), so when the business When there is logic that may fail, the constructor cannot do the job, and a separate initialization function must be written to complete these things.
The example given in the question is actually a misuse. a/b as member variables should be initialized in the constructor. init It would make no sense to initialize it again, which is superfluous. . Moreover, it is best to write the constructor as follows:
I don’t know whether your class was designed by yourself to illustrate the problem or abstracted from the production code.
The issue I want to talk about here is the two-step construction of RAII and objects.
RAII(Resource Acquisition Is Initialization)
I won’t translate it into Chinese.
This should be a term often mentioned in the C++ world.
The main thing is that when the object is created, all the resources it needs have been obtained.
This is very useful for objects created on the stack. The object can be properly constructed without additional processing; and when the object leaves its scope, the resources it acquires are naturally released. Of course, it requires that the constructor and destructor of the class should be well written.
Of course, if you have many places where you need to construct objects on the stack, shared_ptr is indispensable.
Two-step construction
This is the name I gave it (I don’t know what the official name is). Many times, doing this is also a helpless move in C++.
For example, this class needs to create a database connection when it is constructed (what? You won't cause trouble for yourself). You should know how painful it is to handle some errors/exceptions in the C++ constructor. At this time, it is a better way to pull out these more cumbersome and error-prone things and put them in the init function. It is also more convenient for you to handle errors in the init function without affecting the semantics of the entire program. Imagine that an object dies in the constructor. How do you recycle this object? Let's use an init function.
With init, you should make a function similar to destroy. You can decide by yourself whether to put it in the destructor or let the caller call it. But I personally think it’s better to let the user adjust it himself. What if something goes wrong during the destroy process?
The cpp object must be initialized when it is defined, which is not flexible enough. If you use dynamic allocation, you may forget to release it. Unlike java.
So sometimes the constructor just assigns default values to each field, and init is the real initialization, which can be called manually when needed. The work of recycling is managed by the destructor.
But now you don’t have to worry so much, just use shared_ptr.
init
Didn’t you write it yourself? What does it have to do with C++?C++ only stipulates constructors.
init()
needs to be declared only when the C++ user feels it is appropriate. It does not mean that every C++ class needs to have ainit()
.Generally speaking, the constructor should only be used to initialize member variables, and additional initialization functions should be used for initialization related to business logic, especially business code that contains error branches.
This is stipulated because the constructor has many restrictions. For example, it cannot return an error code to indicate an error, and it should not throw an exception (because doing so will cause the destructor to not be executed, which often causes problems), so when the business When there is logic that may fail, the constructor cannot do the job, and a separate initialization function must be written to complete these things.
The example given in the question is actually a misuse.
a
/b
as member variables should be initialized in the constructor.init
It would make no sense to initialize it again, which is superfluous. . Moreover, it is best to write the constructor as follows:I don’t know whether your class was designed by yourself to illustrate the problem or abstracted from the production code.
The issue I want to talk about here is the two-step construction of RAII and objects.
I won’t translate it into Chinese.
This should be a term often mentioned in the C++ world.
The main thing is that when the object is created, all the resources it needs have been obtained.
This is very useful for objects created on the stack. The object can be properly constructed without additional processing; and when the object leaves its scope, the resources it acquires are naturally released. Of course, it requires that the constructor and destructor of the class should be well written.
Of course, if you have many places where you need to construct objects on the stack, shared_ptr is indispensable.
This is the name I gave it (I don’t know what the official name is). Many times, doing this is also a helpless move in C++.
For example, this class needs to create a database connection when it is constructed (what? You won't cause trouble for yourself). You should know how painful it is to handle some errors/exceptions in the C++ constructor. At this time, it is a better way to pull out these more cumbersome and error-prone things and put them in the init function. It is also more convenient for you to handle errors in the init function without affecting the semantics of the entire program. Imagine that an object dies in the constructor. How do you recycle this object? Let's use an init function.
With init, you should make a function similar to destroy. You can decide by yourself whether to put it in the destructor or let the caller call it. But I personally think it’s better to let the user adjust it himself. What if something goes wrong during the destroy process?
Thank you all, it’s really enlightening, but as a newbie, my question seems to be too low-end, Loli Town Building
The cpp object must be initialized when it is defined, which is not flexible enough. If you use dynamic allocation, you may forget to release it. Unlike java.
So sometimes the constructor just assigns default values to each field, and init is the real initialization, which can be called manually when needed. The work of recycling is managed by the destructor.
But now you don’t have to worry so much, just use shared_ptr.