<item 5> Know What functions C + + silently writes and calls
1, If you don ' t declare them yourself, compilers would declare their own of a copy versions, a copy constructor o Perator, and a destructor. Furthermore, if you declare no constructors @ All, compilers would also declare a default constructor for you. All these functions is both public and inline (see Item 30). These functions is generated only if they is needed, but it doesn ' t take much to need them. The following code would cause each function to be generated:
Empty E1; // default constructor; // destructor Empty E2 (E1); // copy constructor e2 = E1; // copy assignment operator
2. What do the compiler's default generated functions do? Well, the default constructor and the destructor primarily give compilers a place to put "behind the scenes" code such as Invocation of constructors and destructors of base classes and non-static data members. Note that the generated destructor are non-virtual (see ITEM7) unless it's for a class inheriting from a base class that it Self declares a virtual destructor (in which case, the function ' s virtualness comes from the base class). As for the copy constructor and the copy assignment operator, the compiler-generated versions simply copy each non-static data member of the source object over to the target object.
3, compiler-generated copy assignment operators behave as I ' ve described only then the resulting code is both legal and have A reasonable chance of making sense. If either of these tests fails, compilers would refuse to generate a operator= for your class.
template<classT>classNamedobject { Public://This ctor no longer takes a const name, because Namevalue//is now a reference-to-non-const string. The char* constructor//is gone, because we must has a string to refer to.Namedobject (std::string& Name,Constt&value), .....//as above, assume no//Operator= is declaredPrivate: std::string& Namevalue;//This was now a referenceConstT ObjectValue;//This was now const};STD::stringNewdog ("Persephone"); std::stringOlddog ("Satch"); Namedobject<int> P (Newdog,2);//When I originally wrote this, we//Dog Persephone was on to//Has her second birthdaynamedobject<int> S (olddog, $);//The family dog Satch (from my//childhood) would be + if she//were still alivep = s;//What should happen to//The data members in p?
C + + doesn ' t provide a by-reference refer to a different object. Faced with this conundrum, C + + refuses to compile the code. If you want-to-support assignment-a class containing a reference member, you must define the copy assignment operator y Ourself. Compilers behave similarly for classes containing const members. Finally, compilers reject implicit copy assignment operators in derived classes this inherit from base classes declaring t He copy assignment operator private. (Copy base class part required, but no access to base class copy function, therefore not generated)
4, things to Remember
Compilers may implicitly generate a class ' s default constructor, copy constructor, copy assignment operator, and Destructo R.
<item 6> explicitly disallow the use of compiler-generated functions you does not want
5, Instead, declare the copy constructor and the copy assignment operator private. By declaring a member function explicitly, you prevent compilers from generating their own version, and by making the Func tion Private, you keep people from calling it.
6. If you do not want the friend function and member function calls further: This trick-declaring member functions private and deliberately not implementing them-is so well Established, it's used to prevent copying in several classes in C + + ' s IOStreams library. Take a look, for example, at the definitions of Ios_base, Basic_ios, and sentry in your standard library implementation. You'll find that in each case, both the copy constructor and the copy assignment operator is declared private and is not Defined. (Common convention: Use only parameter types to omit parameter names when declaring, this type is link-time error.)
7, It ' s possible to move the Link-time error up to compile time (always a good thing-earlier error detection is better th An later) by declaring the copy constructor and copy assignment operator private not in Homeforsale itself, but in a base Class specifically designed to prevent copying. The base class is simplicity itself:
classuncopyable {protected://Allow constructionUncopyable () {}//and destruction of~uncopyable () {}//derived Objects ...Private: Uncopyable (Constuncopyable&);//... but prevent copyinguncopyable&operator=(Constuncopyable&);};classHomeforsale:Privateuncopyable {//class no longer...//declares copy ctor or};//copy assign. Operator
so Homeforsale can no longer replicate and assign values
8, std::vector implementation of the premise is that the object can be copied, in most cases, we should store the object's reference instead of the value.
9. The implementation and use of uncopyable include some subtleties, such as the fact, inheritance from uncopyable need N ' t is public (see Items, and all) and that Uncopyable's destructor need not is virtual (see Item 7). Because uncopyable contains no data, it's eligible for the empty base class optimization described in Item all, but Because It's a base class, use of this technique could leads to multiple inheritance (see Item 40). Multiple inheritance, in turn, can sometimes disable the empty base class optimization (again, see Item 39). In general, you can ignore these subtleties and just use uncopyable as shown, because it works precisely as advertised. You can also with the version available at Boost (see Item 55). That's class is named Noncopyable. It's a fine class, I just find the name a bit un-, er, non natural.
10,things to Remember
? To disallow functionality automatically provided by compilers, declare the corresponding member functions private and give No implementations. Using a base class like uncopyable is one-to-do.
<item 7> Declare destructors virtual in polymorphic base classes
11. C + + Specifies if a derived class object is deleted through a pointer to a base class with a non-virtual destruct Or, results is undefined. What typically happens at runtime is, the derived part of the object is never destroyed. Eliminating the problem is simple:give the base class A virtual destructor. Then deleting a derived class object would do the exactly what you want. It will destroy the entire object, including all its derived class parts:(even if multiple units are used, defining a virtual destructor in a base class is not necessarily the truth, for example because abi/(applicat Ion binary Interface applies the binary interface), COM no longer uses the virtual destructor in the interface definition, nor does it use New/delete. Any class with virtual functions should almost certainly has a virtual destructor.
15. If A class does not contain virtual functions, then often indicates it is not meant to be used as a base class. When a class was not intended to be a base class, making the destructor virtual was usually a bad idea.
<effective c++> Reading notes--ctors, dtors and assignment Operators