C++填坑系列:tip6 如何显式拒绝编译器自动生成的函数

隐藏

概述

方法很简单,分两步:

1.声明并放在private中

2.不去定义它,那么即便member函数或者friend函数调用也将会出现linkage error。

复习private,public,protected

参考自 http://blog.chinaunix.net/uid-722885-id-124903.html

第一:private,public,protected的访问范围:

private: 只能由该类中的函数、其友元函数访问,不能被任何其他访问,该类的对象也不能访问. protected: 可以被该类中的函数、子类的函数、以及其友元函数访问,但不能被该类的对象访问 public: 可以被该类中的函数、子类的函数、其友元函数访问,也可以由该类的对象访问 注:友元函数包括两种:设为友元的全局函数,设为友元类中的成员函数

第二:类的继承后方法属性变化:

使用private继承,父类的所有方法在子类中变为private; 使用protected继承,父类的protected和public方法在子类中变为protected,private方法不变; 使用public继承,父类中的方法属性不发生改变;

水平访问:声明了某类的一个对象,访问其成员函数和数据成员;一般只有public区(不含protected区!)的成员函数和数据成员,可以被水平访问。 垂直访问:一个类从某个基类派生,派生类访问基类的成员函数和数据成员;一般只有public和protected区的成员函数和数据成员,可以被垂直访问。 再次提到:可以提供访问行为的主语为“函数”。类体内的访问没有访问限制一说,即private函数可以访问public/protected/private成员函数或数据成员,同理,protected函数,public函数也可以任意访问该类体中定义的成员public继承下,基类中的public和protected成员继承为该子类的public和protected成员(成员函数或数据成员),然后访问仍然按类内的无限制访问。

对于类域范围内,成员函数访问无所谓访问限制。对于继承情况下的基类private成员,在派生类中仍然继承了下来,只不过它不能直接访问,即使在类里也不行,更不用说是类对象了。

示例 GCC iostream

//文件: ios_base.h
  class ios_base
  {
  public:
  // 省略

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 50.  Copy constructor and assignment operator of ios_base
  private:
    ios_base(const ios_base&);  // 阻止copy 构造函数

    ios_base&
    operator=(const ios_base&); // 阻止copy assignment操作符
  };
//文件: basic_ios.h
template<typename _CharT, typename _Traits>
    class basic_ios : public ios_base  //继承自ios_base
    { //省略 };
//文件: ostream
template<typename _CharT, typename _Traits>
    class basic_ostream : virtual public basic_ios<_CharT, _Traits>
    { //省略 };

template <typename _CharT, typename _Traits>
    class basic_ostream<_CharT, _Traits>::sentry
    //class basic_ostream中的类sentry
    { //省略 };
// ...
//文件: istream
template<typename _CharT, typename _Traits>
    class basic_istream : virtual public basic_ios<_CharT, _Traits>
    { //省略 };

示例 Uncopyable class

// 代码来自Effective C++
class Uncopyable {
protected:    //允许derived class调用构造和析构
  Uncopyable() {}
  ~Uncopyable() {}
private:
  Uncopyable(const Uncopyable&);  //阻止copying
  Uncopyable operator= (const Uncopyable&);
};

class HomeforSale : private Uncopyable {
                   //这种继承实现的方式有可能带来多重继承的问题
    // ...
};

RAII

RAII(resource acquisition is initialization,资源获取即初始化)是一个C++的技巧,或者说是属于C++的设计模式,跟本主题有一定的关系,所以稍微补充一下。

所谓资源获取即初始化,我觉得可以理解为通过类初始化来获取资源,因为类生命周期结束后即会通过析构函数自动释放掉资源,而无需考虑资源释放的问题,这就很爽了。

例如智能指针就是将指针封装成类的RAII技巧。

既然是资源,那就具有唯一性,大多数情况下不能被复制,所以就需要如上所述的uncopyable 技巧,要么自己定义,要么也可以直接用

关于RAII这里不详细展开了, 更多参见: 【C++设计技巧】C++中的RAII机制

       <http://www.jellythink.com/archives/101>

       <http://blog.csdn.net/hunter8777/article/details/6327704>
-----EOF-----

Categories: c++ Tags: c++