转-C++拷贝构造函数详解

c++练习2 实现一个复数类Complex,该类中包括实部 real和虚部imag两个实型数据成员,并具有下述功能: (1)添加构造函数,初始化其数据成员。 (2)重载+算术运算符。 (3)重载==关系运算符。 (4)重载>>流提取运算符,从键盘输入复数的实部和虚部。 (5)重载<<流插入运算符,以标准格式输出一个复数,并当虚部为零时,只输出实部。 #include<iostrea... 阅读详情

http://blog.youkuaiyun.com/lwbeyond/article/details/6202256

一. 什么是拷贝构造函数

首先对于普通类型的对象来说,它们之间的复制是很简单的,例如:

[c-sharp]  view plain copy
  1. int a = 100;  
  2. int b = a;   

而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。
下面看一个类对象拷贝的简单例子。

[c-sharp]  view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. class CExample {  
  5. private:  
  6.      int a;  
  7. public:  
  8.       //构造函数  
  9.      CExample(int b)  
  10.      { a = b;}  
  11.   
  12.       //一般函数  
  13.      void Show ()  
  14.      {  
  15.         cout<<a<<endl;  
  16.       }  
  17. };  
  18.   
  19. int main()  
  20. {  
  21.      CExample A(100);  
  22.      CExample B = A; //注意这里的对象初始化要调用拷贝构造函数,而非赋值  
  23.       B.Show ();  
  24.      return 0;  
  25. }  

运行程序,屏幕输出100。从以上代码的运行结果可以看出,系统为对象 B 分配了内存并完成了与对象 A 的复制过程。就类对象而言,相同类型的类对象是通过拷贝构造函数来完成整个复制过程的。

下面举例说明拷贝构造函数的工作过程。

[c-sharp]  view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. class CExample {  
  5. private:  
  6.     int a;  
  7. public:  
  8.     //构造函数  
  9.     CExample(int b)  
  10.     { a = b;}  
  11.       
  12.     //拷贝构造函数  
  13.     CExample(const CExample& C)  
  14.     {  
  15.         a = C.a;  
  16.     }  
  17.   
  18.     //一般函数  
  19.     void Show ()  
  20.     {  
  21.         cout<<a<<endl;  
  22.     }  
  23. };  
  24.   
  25. int main()  
  26. {  
  27.     CExample A(100);  
  28.     CExample B = A; // CExample B(A); 也是一样的  
  29.      B.Show ();  
  30.     return 0;  
  31. }   

CExample(const CExample& C) 就是我们自定义的拷贝构造函数。可见,拷贝构造函数是一种特殊的 构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量 。


二. 拷贝构造函数的调用时机

在C++中,下面三种对象需要调用拷贝构造函数!
1. 对象以值传递的方式传入函数参数

[c-sharp] view plaincopy
  1. class CExample   
  2. {  
  3. private:  
  4.  int a;  
  5.   
  6. public:  
  7.  //构造函数  
  8.  CExample(int b)  
  9.  {   
  10.   a = b;  
  11.   cout<<"creat: "<<a<<endl;  
  12.  }  
  13.   
  14.  //拷贝构造  
  15.  CExample(const CExample& C)  
  16.  {  
  17.   a = C.a;  
  18.   cout<<"copy"<<endl;  
  19.  }  
  20.    
  21.  //析构函数  
  22.  ~CExample()  
  23.  {  
  24.   cout<< "delete: "<<a<<endl;  
  25.  }  
  26.   
  27.      void Show ()  
  28.  {  
  29.          cout<<a<<endl;  
  30.      }  
  31. };  
  32.   
  33. //全局函数,传入的是对象  
  34. void g_Fun(CExample C)  
  35. {  
  36.  cout<<"test"<<endl;  
  37. }  
  38.   
  39. int main()  
  40. {  
  41.  CExample test(1);  
  42.  //传入对象  
  43.  g_Fun(test);  
  44.   
  45.  return 0;  
  46. }  

调用g_Fun()时,会产生以下几个重要步骤:
(1).test对象传入形参时,会先会产生一个临时变量,就叫 C 吧。
(2).然后调用拷贝构造函数把test的值给C。 整个这两个步骤有点像:CExample C(test);
(3).等g_Fun()执行完后, 析构掉 C 对象。

2. 对象以值传递的方式从函数返回

[c-sharp] view plaincopy
  1. class CExample   
  2. {  
  3. private:  
  4.  int a;  
  5.   
  6. public:  
  7.  //构造函数  
  8.  CExample(int b)  
  9.  {   
  10.   a = b;  
  11.  }  
  12.   
  13.  //拷贝构造  
  14.  CExample(const CExample& C)  
  15.  {  
  16.   a = C.a;  
  17.   cout<<"copy"<<endl;  
  18.  }  
  19.   
  20.      void Show ()  
  21.      {  
  22.          cout<<a<<endl;  
  23.      }  
  24. };  
  25.   
  26. //全局函数  
  27. CExample g_Fun()  
  28. {  
  29.  CExample temp(0);  
  30.  return temp;  
  31. }  
  32.   
  33. int main()  
  34. {  
  35.  g_Fun();  
  36.  return 0;  
  37. }  

当g_Fun()函数执行到return时,会产生以下几个重要步骤:
(1). 先会产生一个临时变量,就叫XXXX吧。
(2). 然后调用拷贝构造函数把temp的值给XXXX。整个这两个步骤有点像:CExample XXXX(temp);
(3). 在函数执行到最后先析构temp局部变量。
(4). 等g_Fun()执行完后再析构掉XXXX对象。

3. 对象需要通过另外一个对象进行初始化;

[c-sharp] view plaincopy
  1. CExample A(100);  
  2. CExample B = A;   
  3. // CExample B(A);   

后两句都会调用拷贝构造函数。


三. 浅拷贝和深拷贝

1. 默认拷贝构造函数

    很多时候在我们都不知道拷贝构造函数的情况下,传递对象给函数参数或者函数返回对象都能很好的进行,这是因为编译器会给我们自动产生一个拷贝构造函数,这就是“默认拷贝构造函数”,这个构造函数很简单,仅仅使用“老对象”的数据成员的值对“新对象”的数据成员一一进行赋值,它一般具有以下形式:

[c-sharp]  view plain copy
  1. Rect::Rect(const Rect& r)  
  2. {  
  3.     width = r.width;  
  4.     height = r.height;  
  5. }  
 
    当然,以上代码不用我们编写,编译器会为我们自动生成。但是如果认为这样就可以解决对象 的复制问题,那就错了,让我们来考虑以下一段代码:
[c-sharp]  view plain copy
  1. class Rect  
  2. {  
  3. public:  
  4.     Rect()      // 构造函数,计数器加1  
  5.     {  
  6.         count++;  
  7.     }  
  8.     ~Rect()     // 析构函数,计数器减1  
  9.     {  
  10.         count--;  
  11.     }  
  12.     static int getCount()       // 返回计数器的值  
  13.     {  
  14.         return count;  
  15.     }  
  16. private:  
  17.     int width;  
  18.     int height;  
  19.     static int count;       // 一静态成员做为计数器  
  20. };  
  21.   
  22. int Rect::count = 0;        // 初始化计数器  
  23.   
  24. int main()  
  25. {  
  26.     Rect rect1;  
  27.     cout<<"The count of Rect: "<<Rect::getCount()<<endl;  
  28.   
  29.     Rect rect2(rect1);   // 使用rect1复制rect2,此时应该有两个对象  
  30.      cout<<"The count of Rect: "<<Rect::getCount()<<endl;  
  31.   
  32.     return 0;  
  33. }  

  这段代码对前面的类,加入了一个静态成员,目的是进行计数。在主函数中,首先创建对象rect1,输出此时的对象个数,然后使用rect1复制出对象rect2,再输出此时的对象个数,按照理解,此时应该有两个对象存在,但实际程序运行时,输出的都是1,反应出只有1个对象。此外,在销毁对象时,由于会调用销毁两个对象,类的析构函数会调用两次,此时的计数器将变为负数。

说白了,就是拷贝构造函数没有处理静态数据成员。

出现这些问题最根本就在于在复制对象时,计数器没有递增,我们重新编写拷贝构造函数,如下:

[c-sharp]  view plain copy
  1. class Rect  
  2. {  
  3. public:  
  4.     Rect()      // 构造函数,计数器加1  
  5.     {  
  6.         count++;  
  7.     }  
  8.     Rect(const Rect& r)   // 拷贝构造函数  
  9.     {  
  10.         width = r.width;  
  11.         height = r.height;  
  12.         count++;          // 计数器加1  
  13.     }  
  14.     ~Rect()     // 析构函数,计数器减1  
  15.     {  
  16.         count--;  
  17.     }  
  18.     static int getCount()   // 返回计数器的值  
  19.     {  
  20.         return count;  
  21.     }  
  22. private:  
  23.     int width;  
  24.     int height;  
  25.     static int count;       // 一静态成员做为计数器  
  26. };  

2. 浅拷贝

    所谓浅拷贝,指的是在对象复制时,只对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的也是浅拷贝。大多情况下“浅拷贝”已经能很好地工作了,但是一旦对象存在了动态成员,那么浅拷贝就会出问题了,让我们考虑如下一段代码:

[c-sharp]  view plain copy
  1. class Rect  
  2. {  
  3. public:  
  4.     Rect()      // 构造函数,p指向堆中分配的一空间  
  5.     {  
  6.         p = new int(100);  
  7.     }  
  8.     ~Rect()     // 析构函数,释放动态分配的空间  
  9.     {  
  10.         if(p != NULL)  
  11.         {  
  12.             delete p;  
  13.         }  
  14.     }  
  15. private:  
  16.     int width;  
  17.     int height;  
  18.     int *p;     // 一指针成员  
  19. };  
  20.   
  21. int main()  
  22. {  
  23.     Rect rect1;  
  24.     Rect rect2(rect1);   // 复制对象  
  25.     return 0;  
  26. }  

    在这段代码运行结束之前,会出现一个运行错误。原因就在于在进行对象复制时,对于动态分配的内容没有进行正确的操作。我们来分析一下:

    在运行定义rect1对象后,由于在构造函数中有一个动态分配的语句,因此执行后的内存情况大致如下:

 

 

    在使用rect1复制rect2时,由于执行的是浅拷贝,只是将成员的值进行赋值,这时 rect1.p = rect2.p,也即这两个指针指向了堆里的同一个空间,如下图所示:

 

当然,这不是我们所期望的结果,在销毁对象时,两个对象的析构函数将对同一个内存空间释放两次,这就是错误出现的原因。我们需要的不是两个p有相同的值,而是两个p指向的空间有相同的值,解决办法就是使用“深拷贝”。


3. 深拷贝

    在“深拷贝”的情况下,对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间,如上面的例子就应该按照如下的方式进行处理:

[c-sharp]  view plain copy
  1. class Rect  
  2. {  
  3. public:  
  4.     Rect()      // 构造函数,p指向堆中分配的一空间  
  5.     {  
  6.         p = new int(100);  
  7.     }  
  8.     Rect(const Rect& r)  
  9.     {  
  10.         width = r.width;  
  11.         height = r.height;  
  12.         p = new int;    // 为新对象重新动态分配空间  
  13.         *p = *(r.p);  
  14.     }  
  15.     ~Rect()     // 析构函数,释放动态分配的空间  
  16.     {  
  17.         if(p != NULL)  
  18.         {  
  19.             delete p;  
  20.         }  
  21.     }  
  22. private:  
  23.     int width;  
  24.     int height;  
  25.     int *p;     // 一指针成员  
  26. };  

此时,在完成对象的复制后,内存的一个大致情况如下:

 

此时rect1的p和rect2的p各自指向一段内存空间,但它们指向的空间具有相同的内容,这就是所谓的“深拷贝”。


3. 防止默认拷贝发生

    通过对对象复制的分析,我们发现对象的复制大多在进行“值传递”时发生,这里有一个小技巧可以防止按值传递——声明一个私有拷贝构造函数。甚至不必去定义这个拷贝构造函数,这样因为拷贝构造函数是私有的,如果用户试图按值传递或函数返回该类对象,将得到一个编译错误,从而可以避免按值传递或返回对象。

[c-sharp]  view plain copy
  1. // 防止按值传递  
  2. class CExample   
  3. {  
  4. private:  
  5.     int a;  
  6.   
  7. public:  
  8.     //构造函数  
  9.     CExample(int b)  
  10.     {   
  11.         a = b;  
  12.         cout<<"creat: "<<a<<endl;  
  13.     }  
  14.   
  15. private:  
  16.     //拷贝构造,只是声明  
  17.     CExample(const CExample& C);  
  18.   
  19. public:  
  20.     ~CExample()  
  21.     {  
  22.         cout<< "delete: "<<a<<endl;  
  23.     }  
  24.   
  25.     void Show ()  
  26.     {  
  27.         cout<<a<<endl;  
  28.     }  
  29. };  
  30.   
  31. //全局函数  
  32. void g_Fun(CExample C)  
  33. {  
  34.     cout<<"test"<<endl;  
  35. }  
  36.   
  37. int main()  
  38. {  
  39.     CExample test(1);  
  40.     //g_Fun(test); 按值传递将出错  
  41.       
  42.     return 0;  
  43. }   

四. 拷贝构造函数的几个细节

1. 拷贝构造函数里能调用private成员变量吗?
解答:
这个问题是在网上见的,当时一下子有点晕。其时从名子我们就知道拷贝构造函数其时就是
一个特殊的构造函数,操作的还是自己类的成员变量,所以不受private的限制。


2. 以下函数哪个是拷贝构造函数,为什么?

[c-sharp]  view plain copy
  1. X::X(const X&);      
  2. X::X(X);      
  3. X::X(X&, int a=1);      
  4. X::X(X&, int a=1, int b=2);  

解答:对于一个类X, 如果一个构造函数的第一个参数是下列之一:
a) X&
b) const X&
c) volatile X&
d) const volatile X&
且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数.

[c-sharp]  view plain copy
  1. X::X(const X&);  //是拷贝构造函数      
  2. X::X(X&, int=1); //是拷贝构造函数     
  3. X::X(X&, int a=1, int b=2); //当然也是拷贝构造函数  


3. 一个类中可以存在多于一个的拷贝构造函数吗?
解答:
类中可以存在超过一个拷贝构造函数。

[c-sharp]  view plain copy
  1. class X {   
  2. public:         
  3.   X(const X&);      // const 的拷贝构造  
  4.   X(X&);            // 非const的拷贝构造  
  5. };  

注意,如果一个类中只存在一个参数为 X& 的拷贝构造函数,那么就不能使用const X或volatile X的 对象实行拷贝初始化.

[c-sharp]  view plain copy
  1. class X {      
  2. public:  
  3.   X();      
  4.   X(X&);  
  5. };      
  6.   
  7. const X cx;      
  8. X x = cx;    // error  

如果一个类中没有定义拷贝构造函数,那么编译器会自动产生一个默认的拷贝构造函数。
这个默认的参数可能为 X::X(const X&)或 X::X(X&),由编译器根据上下文决定择哪一个。
C#:(复数类)构建一个复数类,实现复数的加减乘除 一、运行效果截图 二、实验要求 例: 复数类: 构建一个复数类,实现复数的加减乘除。 三、代码示例 using System; namespace ConsoleApp7 { class Program { static void Main(string[] args) { Complex x1 = new Complex(2, 3); Complex x2 = new Complex(5. 阅读详情

相关推荐

C++零基础教程(拷贝构造函数)

本篇文章来讲解C++中的拷贝构造函数,本篇文章就讲解到这里,这一块的知识还是非常重要的大家务必要掌握好。

m0_49476241的博客 1256

C++基础——拷贝构造函数

C++类成员函数之拷贝构造函数

weixin_69283129的博客 2万+

Windows下Python安装geopandas全攻略:解决GDAL依赖问题的5个关键步骤

本文详细解析了在Windows系统下安装Python地理空间分析库geopandas时,如何有效解决其核心依赖GDAL的编译难题。文章提供了五个关键步骤,包括理解依赖关系、获取预编译wheel文件、顺序安装及环境验证,旨在帮助用户绕过复杂的C++编译环境,顺利完成geopandas的安装部署。

weixin_28221501的博客 285

C++——拷贝构造函数

(用旧对象去构造新对象)拷贝构造函数,又称复制构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构造及初始化。值类型(不行,会产生递归);指针类型(能实现要求,但会出现歧义(感觉a的地址给b构造));引用类型(本类对象的const引用)。其唯一的形参必须是引用,但并不限制为const,一般普遍的会加上const限制。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。

weixin_59179454的博客 2万+

COMSOL介电弹性体数值仿真指南:预拉伸圆形DEA的稳态变形分析(I)

本期博客是《COMSOL介电弹性体数值仿真指南》系列博客中的一期。聚焦于介电弹性体驱动器(DEA)中最为经典的预拉伸圆形DEA驱动器构型,对其物理特性及数值仿真总体方案进行介绍与讨论。

忘了面孔的Batou 454

手把手教你学GPU的KMD专栏--2.4 GPU固件加载与初始化流程

GPU固件(Firmware)是嵌入在GPU芯片ROM或EEPROM中的低级代码,是GPU启动时首先执行的程序。它负责GPU硬件的基础初始化和基本功能配置,是GPU与操作系统之间的"第一道桥梁"。与操作系统驱动不同,固件在CPU启动后、操作系统加载前就已执行,是硬件层面的"启动代码"。关键认知:GPU固件是GPU的"BIOS",没有它,GPU硬件无法进入可操作状态。就像CPU需要BIOS来初始化内存和外设一样,GPU需要固件来初始化其核心组件。

MHD0815的博客 112

【转】C++拷贝构造函数详解

一、什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=100; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。 下面看一个类对象拷贝的简单例子。 #include <iostream> using namespace std; class C...

baocha1738的博客 55

《Python Web项目集锦》-专栏介绍和目录

本专栏专注于Python Web项目,涉及内容包含FastAPI、Django、Flask等,所有项目代码完整且可直接运行。不管是零基础还是有经验的开发,相信都能从本专栏获益。有任何问题欢迎私聊博主,专栏持续更新中...

数据知道的博客 5214

c++拷贝构造函数详解(转)

一、什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如 int a=100; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。 下面看一个类对象拷贝的简单例子。 #include<iostream> using namespace std; class CExample { private: int a; public: //构造函数 CExample(int b) { a

ahapeach的博客 304

华为OD机考2025C卷 - 高矮个子排队(Java & Python& JS & C++ & C)

华为OD机考2025C卷 - 高矮个子排队。提供在线OJ刷题。Java、C++、Python、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 1683

SO_KEEPALIVE、TCP_KEEPIDLE、TCP_KEEPINTVL、保活包

是一个套接字选项,用于设置是否启用 keepalive 机制。在这段代码中没有涉及到选项的设置。当被设置为非零值时,表示启用 keepalive 机制。keepalive 是一种用于检测连接是否仍然有效的机制。通过定期发送一些特定的探测数据,可以检测到网络连接的异常中断或对端应用程序的崩溃退出。为了避免以上情况,可以启用 keepalive 机制,即使在无数据传输的情况下也定期发送探测数据。如果在一定时间内没有收到对端的响应,就认为连接已经失效,并进行相应的处理。要启用选项,需要使用函数。其中,fd。

m0_46376834的博客 4816

[转]C++拷贝构造函数详解

转载自:http://blog.youkuaiyun.com/lwbeyond/article/details/6202256?reload 一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: [c-sharp] view plaincopy int a = 100;   in

Tony Fang的Blog 373

PyTorch深度学习实战(41)——循环神经网络与长短期记忆网络

循环神经网络 (Recurrent Neural Network, RNN) 通过将前一个时间步的隐藏状态作为当前时间步的输入,实现对序列数据的建模,由于循环连接的存在,RNN 能够捕获时间依赖关系,然而,RNN 在处理长期依赖性问题时会遇到困难。为了解决这个问题,提出了 LSTM,通过引入门控机制改进 RNN 来有效地处理长期依赖关系。在本节中,了解了 LSTM 和 RNN 的基本原理,并介绍了如何在 PyTorch 中实现 LSTM。

盼小辉丶的博客 1万+

转 C++拷贝构造函数详解

C++拷贝构造函数详解 一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: [c-sharp]view plaincopy inta=100; intb=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。下面看一个类对象拷贝的简单例子。 [c...

weixin_34291004的博客 73

【MicroPython编程-ESP32篇:设备驱动】-BNO08X系列传感器驱动

BNO08X 系列(BNO085/BNO086)是一款系统级封装 (SiP),集成了三轴加速度计、三轴陀螺仪、磁力计以及运行 CEVA SH-2 固件的 32 位 ARM® Cortex™-M0+ 微控制器。SH-2 包含 MotionEngine™ 软件,该软件提供复杂的信号处理算法来处理传感器数据,并提供精确的实时 3D 姿态、航向、校准加速度和校准角速度,以及更高级的上下文输出。BNO08X 集成在一个 28 引脚 LGA 封装中,尺寸为 3.8mm x 5.2mm x 1.1mm。它兼容 Andro

视觉与物联智能 696

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【补足基础】C++类中拷贝构造函数详解【转】

a. C++标准中提到“The default constructor, copy constructor and copy assignment operator, and destructor are special member functions.[Note: The implementation will implicitly declare these member functions

sunnyorange的专栏 840

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

[016]转--C++拷贝构造函数详解

一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: [c-sharp]view plaincopy inta=100; intb=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。下面看一个类对象拷贝的简单例子。 [c-sharp]view plaincopy ...

weixin_30563319的博客 74

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【转】 c++拷贝构造函数(深拷贝,浅拷贝)详解

c++拷贝构造函数(深拷贝,浅拷贝)详解2013-11-05 20:30:29 分类:C/C++ 原文地址:http://blog.chinaunix.net/uid-28977986-id-3977861.html 一、什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: inta=100; intb=a; ...

weixin_30699463的博客 89

【拷贝构造函数】c++类拷贝构造函数详解

【拷贝构造函数】c++类拷贝构造函数详解 一、什么是拷贝构造函数 也称为复制构造函数。 复制构造函数参数为类对象本身的引用,根据一个已存在的对象复制出一个新的对象,一般在函数中会将已存在对象的数据成员的值复制一份到新创建的对象中。 先来看一个例子: 定义一个Time类,该类有三个公有成员 Hour,Minute,Second。 将该类定义在“Time.h”的头文件里。建一个main.cpp用来放主函数。 “Time.h”: #include<iostream> using namespace

leiyulu的博客 6967

C++拷贝构造函数详解

在C++中,拷贝构造函数是一种特殊的构造函数,用于创建一个新对象,并将其初始化为现有对象的副本。拷贝构造函数的函数名必须与类名相同,并且参数为该类的一个常引用。拷贝构造函数是一种特殊的构造函数,用于创建对象的副本。他接受一个同类型的对象(本类对象的引用)作为参数,并使用该对象的数据来初始化新对象。拷贝构造函数通常用于在程序中复制对象,以便在不修改原始对象的情况下对其进行操作。拷贝构造函数通常会执行深拷贝操作,即复制指针指向的数据,而不是仅仅复制指针本身。

m0_62573214的博客 4073

C++——拷贝构造函数详解

C++——拷贝构造函数1拷贝构造函数的特点:2通过例子引入拷贝构造:3构造对象的时候使用引用返回与不使用引用返回的问题:3.1不使用引用返回3.2引用返回——从已经死亡的地址接收值不牢靠 1拷贝构造函数的特点: 函数名和类型名一样 Object(const Object& obj) { } 上面的形参里面需要加上“&”,目的是为了防止无限的构造,形成死递归。 加上const,目的是常引用,不能改变里面的值 2通过例子引入拷贝构造: 问:下面的fun函数在调用的过程中创建了几个对象?(答:五

仟各的博客 1万+

C++ 拷贝构造函数详解

C++ 拷贝构造函数详解 下面的讲解将以C++标准库的string类作为讲解对象,string类:class with pointer member(s) 1、拷贝构造函数和拷贝赋值函数 1.1引入 下面是给出的测试函数,也是我们要能在自己设计的myString类中实现的功能: int main() { myString s1(); //无参数构造函数 myString s2("Hello world!"); //传入字符串的构造函数 myString s3(s1); //

weixin_45745854的博客 4148
上一篇: wy实习面试
下一篇: 转-static_cast、dynamic_cast reinterpret_cast和const_cast
lightty
博客等级 码龄17年 59粉丝 147原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值