C++点点滴滴

原创 2004年09月30日 18:06:00
对象作为参数传给函数,以及函数返回对象的问题

1, 当对象作为参数直接传给函数时(passing object by value),作为该对象的一个拷贝,一个新的对象会产生。
但是需要注意的是:
该新的对象被自动创建的时候,构造函数(constructor)并不被调用,而是复制构造函数(copy constructor)被调用;因为构造函数是初始化一个对象,而作为传入函数的参数,是现有对象的一个拷贝。
当函数结束的时候,为了参数而新创建的对象的生命周期也会结束,因此,这个时候,对象的析构函数(destructor)会被调用。

2, 当函数返回一个对象的时候,需要注意的是,如果该返回值不被明确地赋值给一个对象的话,一个临时的对象会被自动创建,用于其他可能的计算;同样的,对象的返回(无论是否临时对象),对象的复制构造函数会被调用,而不是构造函数;当临时对象完成使命(返回 has been returned)后,对象的析构函数(destructor)会被调用。

因此,对象作为参数传给函数,以及函数返回对象的时候,特别需要注意对象的成员中有指针的情况。
 
关于复制构造函数(copy constructor)

当一个变量通过一个现有的对象被创建的时候,复制构造函数会被调用。

存在于下面三种情况(注意,赋值操作的时候,并不会被调用):
1,声明一个变量的时候,同时初始化该变量
---------------------------------------------------------------------------------
Person q("Mickey");      // 构造函数被调用
Person r(p);                  // 复制构造函数被调用
Person p = q;                // 复制构造函数被调用
 p = q;                          //  这是一个赋值操作, 构造函数复制构造函数被调用
---------------------------------------------------------------------------------
2, 当对象作为参数直接传给函数时(passing object by value)
3, 当函数返回一个对象的时候

参考: http://www.fredosaurus.com/notes-cpp/oop-condestructors/copyconstructors.html  

● 关于运算符重载(operator overloading)

运算符重载可以通过成员函数(member functions)友好函数(friend functions)实现。
但是有以下的限制:
1, 不能改变运算符的优先级
2, 不能创建新的运算符
3, 不能重载 :: sizeof ?: . **
      (Thinking in C++:   .    .*   **)

4, 重载+并不意味着同时重载了+=,其他-=等也是同样
5, 重载 =,[],-> ,() 运算符的时候,只能通过成员函数实现,从而强制使得左操作数类型是所定义的类
6, ++ 和 -- 的重载需要特殊的处理 (a++/a--和++a/--a的区别)
7, = 的重载需要特殊的考虑 (自我判断,指针的释放和分配)

Thinking in C++:   
Murray 对于操作符重载是否使用成员函数有如下建议
:
操作符建议
所有的一元符号成员函数
= ( ) [ ] –> –>*必须是成员函数
+= –= /= *= ^=
&= |= %= >>= <<=
成员函数
所有的二元符号非成员函数

● 关于函数隐藏
子类可以通过改变返回值或者参数来隐藏父类的函数,但如果该函数是虚拟函数的话,则只能通过改变参数而不能通过改变返回值来隐藏该函数,因为相同参数的虚拟函数只能覆盖而不能隐藏,而覆盖只能返回相同的返回值类型(或者该类型的派生类)。

● 关于继承
1,构造函数,复制构造函数,析构函数,赋值(=)操作符号函数并不会自动被继承,而是被综合(synthesized)
2,如果子类明确定义了复制构造函数/赋值操作符号函数,必须明确调用父类的相应的复制构造函数/赋值操作符号函数,否则父类的缺省构造函数会被调用。
3,赋值操作符号函数只综合相同类型对象的赋值。

From <<Thinking in C++>>

----------------------------------------------------------------------------------------------

//:! :CopyRight.txt
(c) 1995-2004 MindView, Inc.  All rights reserved.

#include <iostream>
  std;

 GameBoard {
:
  GameBoard() { cout << ; }
  GameBoard( GameBoard&) { 
    cout << ; 
  }
  GameBoard& =( GameBoard&) {
    cout << ;
     *;
  }
  ~GameBoard() { cout << ; }
};

 Game {
  GameBoard gb; 
:
  
  Game() { cout << ; }
  
  
  
  Game( Game& g) : gb(g.gb) { 
    cout << ; 
  }
  Game() { cout << ; }
  Game& =( Game& g) {
    
    
    
    gb = g.gb;
    cout << ;
     *;
  }
   Other {}; 
  
   Other()  {
    cout << ;
     Other();
  }
  ~Game() { cout << ; }
};

 Chess :  Game {};

 f(Game::Other) {}

 Checkers :  Game {
:
  
  Checkers() { cout << ; }
  
  
  
  Checkers( Checkers& c) : Game(c) {
    cout << ;
  }
  Checkers& =( Checkers& c) {
    
    
    
    Game::=(c);
    cout << ;
     *;
  }
};

 main() {
  Chess d1;  
  Chess d2(d1); 

  d1 = d2; 
  f(d1); 
  Game::Other go;

           
  Checkers c1, c2(c1);
  c1 = c2;
} 

--------------------------------------------------------------
GameBoard()
Game()
GameBoard(const GameBoard&)
Game(const Game&)
GameBoard::operator=()
Game::operator=()
Game::operator Other()
GameBoard()
Game()
Checkers()
GameBoard(const GameBoard&)
Game(const Game&)
Checkers(const Checkers& c)
GameBoard::operator=()
Game::operator=()
Checkers::operator=()
~Game()
~GameBoard()
~Game()
~GameBoard()
~Game()
~GameBoard()
~Game()
~GameBoard()
--------------------------------------------------------------


● 关于异常
1,当一个异常在所有的层次都不被捕获的时候,terminate()会被调用
2,当一个局部变量的析构函数中抛出异常的时候,terminate()会被调用;当一个全局变量或者static变量的构造函数或者析构函数种抛出异常的时候,terminate()会被调用。
3,当一个对象在构造函数中抛出异常的时候,它的析构函数不会被调用。


参考资料
http://www.fredosaurus.com/notes-cpp/
<<Thinking in C++>> 2ed   2000 by Bruce Eckel 

Jady Leung 2004年9月30日创建
                  2005年2月28日更新,增加<<Thinking in C++>>内容

进公司的点点滴滴

2015年2月2日,我进了悦厚科技,同时也是我们部门的第一女生,刚进公司那会,感觉他们都很好,老大帮我弄好了所有的东西,而安静帮我安装了Google,而胡哥却是很低调的。到了中午他们一起带我去吃饭,饭...
  • nlwx520
  • nlwx520
  • 2016年03月30日 17:39
  • 254

大学生活的点滴感悟

仅以此文jilu
  • wqztmx4
  • wqztmx4
  • 2014年05月18日 00:20
  • 618

总结一下自己IT从业一年的点点滴滴

我是一个三流二本学校出来的学渣(我并不是在贬低我的学校,在我心中她是最伟大的),专业是计算机科学与技术,大学里虽然挂科不多,但是专业知识完全为0,也从没想过有一天会从事IT这个行业。然而现实总是与理想...
  • niyehunwu
  • niyehunwu
  • 2016年01月10日 21:24
  • 357

Python的点点滴滴(filesystem paths)

测试用例的Script要动态加载,这涉及到文件系统中可用测试用例的遍历问题。在Python3.4中,提供了一个OO的路径管理工具pathlib,可以使用pathlib来完成列出系统可用测试用例集的功能...
  • coroutines
  • coroutines
  • 2014年12月17日 09:44
  • 728

项目点滴

工程中往往出现的事情是全组都没有预料到的。比如:一个程序块无法实现。或者一个程序块与已经编写的程序块无法连接到一起。这就要求项目管理者要马上做出选择,要么马上放弃该功能模块,要么马上利用另外的可以实现...
  • cctt_1
  • cctt_1
  • 2006年07月28日 21:49
  • 924

培养成功孩子生活中的点点滴滴

需要家长每天都要心中有数,训练内容有以下几方面,每天针对计划表中的内容灵活实施,坚持下去,相信最后孩子会受益非浅的。 计划表如下: 周 一 周二 周三 周四 周五 周六 ...
  • zhengleiqing
  • zhengleiqing
  • 2016年04月07日 17:42
  • 272

半年收获的点点滴滴

半年收获的点点滴滴     进入提高班学习了一又二分之一年了,是时候清点一下这半年的收获了。这半年经历了很多的事,当让在这过程中,我也收获了很多。 技术上的收获:     这半年我学习的东西不如别人...
  • m15732622413
  • m15732622413
  • 2016年02月26日 20:02
  • 657

2013--2014年总结——拾掇 “点点滴滴回忆”一

暑假写一年总结,寒假写半年总结。其实都是一样,每次都把以前博客翻出来,看看这半年,这一年,我都干了点什么。因为不这么做,当我坐在电脑前,要准备写总结的时候,我发现,我做到了“GTD”,呵呵,把这一年给...
  • wangyongxia921
  • wangyongxia921
  • 2014年09月15日 08:11
  • 1530

从今天开始,记录下在公司的点点滴滴。

公司不给上外网啊...木有办法只好用这样的方式了.   今天由于家里还是不能上网,所以果断来公司加班以防止在家成为胡子拉碴的宅男过一天跟AI三国杀的日子.   来到办公室发现没有什么人,于是想起这...
  • hamxyy
  • hamxyy
  • 2011年08月20日 11:11
  • 831

珍惜人生路上的点点滴滴

珍惜人生路上的点点滴滴-------     人的一生是短暂的,也是稍纵即逝的...重新审视品味人生的时候, 我们会发现,人没有满足,就没有欢乐,记住“...
  • dreamlovezone
  • dreamlovezone
  • 2014年12月13日 09:32
  • 462
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++点点滴滴
举报原因:
原因补充:

(最多只允许输入30个字)