effective c++(05)(06)之c++默默编写并调用的函数

1. 当只写一个空类的时候,编译器会为他声明一个copy构造函数,一个copy assignment函数和一个析构函数。以下:c++

若是写下:函数

class Empty{ };

编译器就会实现如下代码:spa

class Empty{
    Empty(){}  //默认构造函数
    Empty(const Empty& rhs ) {}  //复制构造函数
~Empty() {} //析构函数 Empty& operator=( const Empty& rhs ) {} // 复制赋值操做符
};

编译器产生的是non-virtual函数。默认产生以上四种构造函数。code

若是要使这些编译器默认产生的函数失效则提供了如下两种方法:对象

一. 将这些函数声明为private。以下:blog

class Empty{
public:
private:
    Empty(const Empty& rhs ) {}
};

此时若是进行以下调用:编译器

    Empty e1;
    Empty e2(e1);
    return 0;

编译器就不会容许。可是这种状况在member函数或者friend函数内进行的时候就能够作到。string

二. 为了可以保证全部的成员以及类不可以拷贝对象,须要定义如下类:编译

class Uncopyable{
protected:
    Uncopyable() {}
    ~Uncopyable(){}
private:
    Uncopyable( const Uncopyable& );
    Uncopyable& operator=( const Uncopyable& );
};

而后使class

class Empty:private Uncopyable{
    .......
};

这样,当任何人(甚至是member函数或者friend函数)尝试拷贝Empty对象时,编译器试着生成一个copy构造函数和一个copy assignment操做符,而这些函数却尝试着调用base class对应的兄弟,此时编译器便拒绝操做。

2.

class NamedObject{
public:
    NamedObject( const char* name, const T& value );
    NamedObject( const string& name, const T& value );

private:
    string nameValue;
    T objectValue;
};
NamedObject<int> no1( "Smallest Prim Number", 2 );
NamedObject<int> no2(no1);

编译器已经为NamedObject类定义了copy构造函数,因此  NamedObject<int> no2(no1)  就调用了该copy构造函数。

3.

template< typename T >
class NamedObject{
public:
    NamedObject( const string& name, const T& value );

private:
    string& nameValue;
    const T objectValue;
};
string newDog("persephone");
string oldDog("Satch");
NamedObject<int> p( newDog, 2 );
NamedObject<int> s( oldDog, 36 );
p = s;

c++不容许“让reference”指向不一样的对象。若是打算在一个内含有“reference”成员的class内支持赋值操做,必需要定义一个copy assignment操做符。一样对于内含const的成员的类,更改const也是不合法的。

4. 若是某个base class将copy assignment声明为private,编译器也拒绝为其derived classes生成copy assignment操做符。由于编译器为derived classes生成的copy assignment操做符能够处理base class成分。

总结:编译器能够暗自为class建立default构造函数,copy构造函数,copy assignment操做符以及析构函数。

相关文章
相关标签/搜索