惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
V
Vulnerabilities – Threatpost
GbyAI
GbyAI
P
Proofpoint News Feed
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
A
About on SuperTechFans
T
Tenable Blog
M
MIT News - Artificial intelligence
IT之家
IT之家
I
Intezer
D
DataBreaches.Net
爱范儿
爱范儿
T
Threatpost
C
CERT Recently Published Vulnerability Notes
云风的 BLOG
云风的 BLOG
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
K
Kaspersky official blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
Y
Y Combinator Blog
Cyberwarzone
Cyberwarzone
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
Spread Privacy
Spread Privacy
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
AWS News Blog
AWS News Blog
博客园 - 聂微东
C
Check Point Blog
S
Securelist
有赞技术团队
有赞技术团队
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
Last Week in AI
Last Week in AI
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
D
Docker
G
GRAHAM CLULEY
T
The Exploit Database - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tailwind CSS Blog
L
Lohrmann on Cybersecurity
G
Google Developers Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LangChain Blog

博客园 - dgz

c/c++之预处理 虚函数和接口的差别 CALLBACK 函数 vc中LNK2001错误以及解决方案(转载) C++类对象的拷贝构造函数(转载) C++的static关键字(转载) 指针常量,常量指针 static 和 const的解释(转载) 数据类型转换:static_cast,const_cast等用法(转载) static用法小结(转载) Windows多线程多任务设计初步 最简单的完成端口代码 SOCKET模型之重叠I/O篇(转贴) WindowsSockets2.0:使用完成端口高性能,可扩展性Winsock服务程序(转载) CListCtrl 使用技巧(转载) C++字符串—— Win32 字符编码 com+调试 com+返回recordset 如何在VC++ 编写的组件中使用 ADO
派生类的拷贝构造函数
dgz · 2007-08-23 · via 博客园 - dgz

刚刚弄了一个关于派生类的实验,里面涉及到了派生类的拷贝构造函数,这时才发现自己在这个知识点上还很模糊。在CSDN上面看了下相关的一篇文章后,稍微有了点感觉。现总以一个例子总结如下:

情况(1).  派生类的copy   constructor未定义

#include   <iostream>  
  using   namespace   std   ;  
   
  class   base  
  {  
  public:  
  base()   {   cout   <<   "base::base()"   <<   endl   ;   }  
  base(   const   base&   )   {   cout   <<   "base::base(   const   base&)"   <<   endl   ;   }  
  virtual   ~base()   {   cout   <<   "base::~base()"   <<   endl   ;   }  
  };  
   
  class   child   :   public   base  
  {  
   
  public:  
  child()   {   cout   <<   "child::child()"     <<   endl   ;   }  
  /*------------------------------------------------------------------  
  child(   const   child&   )   {   cout   <<   "child::child(   const   child&   )"  <<   endl   ;   }      
  child(const base &)   {cout<<"child::child(const base&)"<<endl;
  -------------------------------------------------------------------*/  
  ~child()   {   cout   <<   "child::~child()"   <<   endl   ;   }  
  int   test(int   i)   {   cout   <<   "int   child::test(int)"   <<   endl   ;  

return   0   ;   }  
   
  };  
   
  int  main()  
  {  
  child   c1   ;  
  cout   <<   "----------------------------"   <<   endl   ;  
  child   c2(c1)   ;  
  cout   <<   "----------------------------"   <<   endl   ;  
  }  
输出结果:  
  base::base()  
  child::child()  
  ----------------------------  
  base::base(   const   base&) 
  ----------------------------  
  child::~child()  
  base::~base()  
  child::~child()  
  base::~base()  

注意  child   c2(c1)   ;   调用了基类的拷贝构造函数,这是为什么呢?因为派生类没有显式定义自己的拷贝构造函数,而基类定义了。首先child公有继承base,且base::copy   ctor也是public的,那么对child类而言,基类copy   ctor是可见的。 child   c2(c1)   ;   这句,编译器先找child自己的copy   ctor,没有。这时就去找基类的copy   ctor。由于它的参数是这样定义的:const   base&   ,即用到了基类对象的引用,所以这里有多态的能力,比如child   c2(c1)   ;

看下面这个例子

  #include   <iostream>  
  using   namespace   std   ;  
   
  class   base  
  {  
  public:  
  base(){cout<<"base::base()"<< endl;}  
  base(const base& rhs)  
  {  
 cout<<"base::base(const base&)"<<endl;    
 rhs.show();    
  }  
  virtual   void show() const {cout<<"base::show()"<<endl;}  
  virtual   ~base()   {cout<<"base::~base()"<<endl;}  
  };  
   
  class   child:public base  
  {  
  public:  
  child()   {cout<<"child::child()"<<endl;}  
  /*------------------------------------------------------------------  
  child(   const   child&   )   {   cout   <<   "child::child(   const   child&   )"  <<   endl   ;   }     
  -------------------------------------------------------------------*/  
  ~child(){cout<<"child::~child()"<<endl;}  
  virtual void show()const {cout<<"child::show()"<<endl;}  
  int  test(int i) {cout<<"int child::test(int)"<<endl;return 0;}  
  };  
   
  int   main()  
  {  
   child   c1   ;  
   cout<<"----------------------------"<<endl;  
   child   c2(c1);  
   cout<<"----------------------------"<<endl;  
  }  

 输出为:

  base::base()  
  child::child()  
  ----------------------------  
  base::base(   const   base&)  

  child::show()
  ----------------------------  
  child::~child()  
  base::~base()  
  child::~child()  
  base::~base()  

2基类也没有显式定义自己的拷贝构造函数

 #include   <iostream>  
  using   namespace   std   ;  
   
  class   base  
  {  
  public:  
  base()   {   cout   <<   "base::base()"   <<   endl   ;   }  
  /*base(   const   base&   )   {   cout   <<   "base::base(   const   base&)"   <<   endl   ;   }   */
  virtual   ~base()   {   cout   <<   "base::~base()"   <<   endl   ;   }  
  };  
   
  class   child   :   public   base  
  {  
   
  public:  
  child()   {   cout   <<   "child::child()"     <<   endl   ;   }  
  /*------------------------------------------------------------------  
  child(   const   child&   )   {   cout   <<   "child::child(   const   child&   )"   <<   endl   ;   }   
  -------------------------------------------------------------------*/  
  ~child()   {   cout   <<   "child::~child()"   <<   endl   ;   }  
  int   test(int   i)   {   cout   <<   "int   child::test(int)"   <<   endl   ;   return   0   ;   }  
   
  };   
    
  int   main()  
  {  
  child   c1   ;  
  cout   <<   "----------------------------"   <<   endl   ;  
  child   c2(c1)   ;  
  cout   <<   "----------------------------"   <<   endl   ;  
  }  

 输出结果:  
  base::base()  
  child::child()  
  ----------------------------   
  ----------------------------  
  child::~child()  
  base::~base()  
  child::~child()  
  base::~base()  

这时child   c2(c1)   ; 调用的是自己的默认拷贝构造函数,同时也会调用基类的默认构造函数(为什么是构造函数不是拷贝构造函数,下面的一种情况就会看到),既然默认的构造函数什么所以不会有什么输出信息。


3基类和派生类都显式定义了自己都拷贝构造函数

#include   <iostream>  
  using   namespace   std   ;  
   
  class   base  
  {  
  public:  
  base()   {   cout   <<   "base::base()"   <<   endl   ;   }   
  base(   const   base&   )   {   cout   <<   "base::base(   const   base&)"   <<   endl   ;   }   
  virtual   ~base()   {   cout   <<   "base::~base()"   <<   endl   ;   }  
  };  
   
  class   child   :   public   base  
  {  
   
  public:  
  child()   {   cout   <<   "child::child()"     <<   endl   ;   }   
  child(   const   child&   )   {   cout   <<   "child::child(   const   child&   )"   <<   endl   ;   }   
  ~child()   {   cout   <<   "child::~child()"   <<   endl   ;   }  
  int   test(int   i)   {   cout   <<   "int   child::test(int)"   <<   endl   ;   return   0   ;   }  
   
  };   
    
  int   main()  
  {  
  child   c1   ;  
  cout   <<   "----------------------------"   <<   endl   ;  
  child   c2(c1)   ;  
  cout   <<   "----------------------------"   <<   endl   ;  
  }  

 输出为:

  base::base()  
  child::child()  
  ----------------------------  
  base::base()  
  child::child(   const   child&   )  
  ----------------------------  
  child::~child()  
  base::~base()  
  child::~child()  
  base::~base()  

注意这里child   c2(c1)   ;   调用了基类的构造函数而不是拷贝构造函数,这又是为什么呢?
请问拷贝构造函数是不是构造函数??   是,是个特殊的构造函数,但是他也是构造函数。C2调用自己的拷贝构造函数的时候,编译器只是认为你调用了构造函数,根据参数类型是调用我们所说的拷贝构造函数,但是当他决定调用基类的哪个构造函数的时候,他要看你传递给基类的参数了,你什么都没有给传递,当然调用默认构造函数了。

我想通过上面三种情况的讲解大家应该都能明白派生类拷贝构造函数的奥妙了,通过这个例子也对我学习C++的过程敲了下警钟:知识面还是不广,综合运用所学东西的能力还不够,尤其是那个多态的地方,如果是单独的多态可能一下子就看出来了,但是用在这里就傻眼了。