重新学习 c++ 的点点滴滴

1. 构造 函数 初始化所有数据成员           (是)
  a。 构造函数是用一种明确定义的状态来设置对象
  b。 对象的状态由数据成员反应
2. 析构函数                             (是)
  a. 类 是否分配了资源,会不会自动释放?
  b. 构造函数里面包含了new表达式的类,析构函数应该加上delete表达式

3. 虚析构函数                            (情况)
 a.  绝不会用作基类的类,不需要需析构函数
 b.  任何虚函数,只有派生时才有用,虚函数是动态绑定的基础
 c.  声明基类指针指向的派生类对象时,delete 此指针会掉用基类的虚构函数,不会调用派生类的析构函数
     派生类的资源不会被销毁,内存泄露
 d.   虚析构函数通常是空的  
  Base* base[2] = {
    new Derived1(),
    new Derived2("Bob")      
  };
  for (int i = 0; i != 2; ++i) {
    delete base[i];    
  }
  备注:
 也 就是说,在基类的析构函数为非虚析构函数的时候,并不一定会造成内存泄漏;当派生类对象的析构函数中有内存需要收回,并且在编程过程中采用了基类指针指向派生类对象,如为了实现多态,并且通过基类指针将该对象销毁,这时,就会因为基类的析构函数为非虚析构函数而不触发动态绑定,从而没有调用派生类的析构函数而导致内存泄漏。

 (基类,如果虚析构函数,就会调用派生类的虚构函数)
  虚析构函数,增加开销
4. 复制构造函数
 a. 构造函数内分配资源,需要复制构造函数
 b. 复制类的对象时,数据成员以及基类对象不能全部复制,需要复制构造函数和
 c. 有非空析构函数的类,一般需要复制构造函数
 d. 复制构造函数一般需要定义赋值操作符。
     X(const X &);
     X& operator=(const X&);

5. 赋值操作符:
  a. 类的对象赋给本身,注意不要错误删除指针?

6. 删除数组 delete[]
 
7. 复制构造函数,赋值操作符 参数类型加const
   a. 复制对象不会改变原对象
   b. 绑定一个非const引用到一个临时对象是非法的
     X(const X &);
     X& operator=(const X&);
8.  函数的引用参数,必须是const吗?
  a. 函数想改变参数,不必使用

9. 成员函数为const ?
  a. 成员函数,不用修改对象,用const
     int length() const

代理类 (surrogate): 一个容器中,存储不同对象

1. 容器 通常包含一种类型对象

   virtual X()=0;   空的,可以不定义

2. 虚复制函数
 a. 每个派生类中均添加一个新的成员函数copy,指向派生类的新建副本
  Vehicle * Truck::copy() const
  {
     return new Truck(*this);
  }
 b. 基类一定要有虚析构数。

3. 代理类(复制对象时)

扫描二维码关注公众号,回复: 4724839 查看本文章

  1. 定义行为与基类相似,并且潜在的表示了所有基类对象的东西,这种类的对象叫做代理
  2. 虚函数copy完成复制工作

   Class VehicelSurrogate{
      public:
         
          VehicelSurrogate();
          VehicelSurrogate(const Vehicle&) //为继承Vehicle的类的对象创建代理
         ~VehicelSurrogate(),
          VehicelSurrogate(const VehicelSurrogate&);
          VehicelSurrogate & operate=(const VehicelSurrogate&);
    private:
          Vehicel *vp;

   };
  3. 空代理(类似零指针)
       VehicelSurrogate::VehicelSurrogate():vp(0){}
       VehicelSurrogate::VehicelSurrogate(const Vehicle& v):vp(v.copy()){}
       VehicelSurrogate::~VehicelSurrogate(){delete *vp}
       VehicelSurrogate::VehicelSurrogate(const VehicelSurrogate& v):
            vp(v.vp?v.vp->copy():0){}
       VehicelSurrogate::VehicelSurrogate& operate=(const VehicelSurrogate& v)
       {
                   if(this!=&v)
                     delete vp;
                     vp=(v.vp?v.vp->copy():0);
                   }
                  return *this;

       }

     a. 对copy调用是一个虚拟调用(因为基类是虚基类,对象不存在)
     b.  v.vp 为1,v.vp->copy()才能被调用
     c.  赋值操作符检测,确保没有把代理赋给自身

--------------------------------------------------------------    
句柄 handle: 为了避免不必要的对象复制(重新读) 6,7 章
**********************************
--------------------------------------------------------------
1. 获取对象: operator->
  class Handle{
   public:
    operate*->();


  }

2.
--------------------------------------
友元:friend

1. 友元函数: 不是类的函数,却能访问类中的所有成员
        class A
        {
          public:
            friend void set_show(int x, A &a);      //该函数是友元函数的声明
          private:
            int data;
        };

        void set_show(int x, A &a)  //友元函数定义,为了访问类A中的成员
        {
            a.data = x;
            cout << a.data << endl;
        }
        int main(void)
        {
            class A a;
            set_show(1, a);
            return 0;
        }
2. 友元类
   
    友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。
关于友元类的注意事项:

(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明。

   #include <iostream>
   using namespace std;

   class A
   {
   public:
      friend class C;                         //这是友元类的声明
   private:
      int data;
   };

   class C             //友元类定义,为了访问类A中的成员
   {
   public:
        void set_show(int x, A &a) { a.data = x; cout<<a.data<<endl;}
   };

   int main(void)
   {
    class A a;
    class C c;
    c.set_show(1, a);
    return 0;
}
3. 友元成员函数
   使类B中的成员函数成为类A的友元函数,这样类B的该成员函数就可以访问类A的所有成员了。
    #include <iostream>

    using namespace std;

    class A;    //当用到友元成员函数时,需注意友元声明与友元定义之间的互相依赖。这是类A的声明
    class B
    {
    public:
        void set_show(int x, A &a);             //该函数是类A的友元函数
    };

    class A
    {
     public:
        friend void B::set_show(int x, A &a);   //该函数是友元成员函数的声明
    private:
        int data;
        void show() { cout << data << endl; }
    };

    void B::set_show(int x, A &a)     
   //只有在定义类A后才能定义该函数,毕竟,它被设为友元是为了访问类A的成员
    {
        a.data = x;
        cout << a.data << endl;
    }

    int main(void)
    {
        class A a;
        class B b;
        b.set_show(1, a);
        return 0;
    }

猜你喜欢

转载自blog.csdn.net/w383117613/article/details/82257842