- 博客(36)
- 资源 (6)
- 收藏
- 关注
原创 条款 37: 决不要重新定义继承而来的非虚函数
假设类 D 公有继承于类 B,并且类 B 中定义了一个公有成员函数 mf。mf的参数和返回类型不重要,所以假设都为 void。换句话说,我这么写: class B {public:void mf();...};class D: public B { ... };D x; // x 是类型 D 的一个对象那么,如果发现这么做:B *pB = &x; // 得到 x
2014-12-31 16:53:43 634
原创 条款 35: 使公有继承体现"是一个" 的含义
C++面向对象编程中一条重要的规则是:公有继承意味着"是一个" 。一定要牢牢记住这条规则。 当写下类 D("Derived" )从类 B("Base")公有继承时,你实际上是在告诉编译器(以及读这段代码的人) :类型 D 的每一个对象也是类型 B 的一个对象,但反之不成立;你是在说:B 表示一个比 D 更广泛的概念,D 表示一个比B 更特定概念;你是在声明:任何可以使用类
2014-12-31 16:37:04 477
原创 条款 30: 避免这样的成员函数:其返回值是指向成员的非 const 指针或引用, 但成员的访问级比这个函数要低
使一个成员为 private 或 protected 的原因是想限制对它的访问,所以写个函数来让用户随意地访问受限的成员没多大意义。所以,如果有个公有函数,返回指向成员的非const指针或引用,成员一般是私有的,那这样就相当于把私有成员暴露给外部接口。 举例如下: class Address { ... }; // 某人居住在此class Person {
2014-12-30 20:33:26 1013
原创 条款 17: 在 operator=中检查给自己赋值的情况
自己给自己赋值的情况: class X { ... }; X a; a = a; // a 赋值给自己 另一种给自己赋值的情况: a = b; 如果 b 是 a 的另一个名字(例如,已被初始化为 a 的引用),那这也是对自己赋值。 在赋值运算符中要特别注意可能出现别名
2014-12-30 19:30:54 662
原创 条款 13: 初始化列表中成员列出的顺序和它们在类中声明的顺序相同
templateclass Array {public:Array(int lowBound, int highBound);...private:vector data; // 数组数据存储在 vector 对象中// 关于 vector 模板参见条款 49size_t size; // 数组中元素的数量int lBound, hBound; // 下限,上限};
2014-12-28 22:38:14 1095
原创 条款 16: 在 operator=中对所有数据成员赋值
实际编程中,这意味着写赋值运算符时,必须对对象的每一数据成员赋值:template // 名字和指针相关联的类的模板class NamedPtr { // (源自条款 12)public:NamedPtr(const string& initName, T *initPtr);NamedPtr& operator=(const NamedPtr& rhs);private:st
2014-12-28 20:48:52 549
原创 条款 6:析构函数里对指针成员调用 delete
大多数情况下,执行动态内存分配的的类都在构造函数里用 new 分配内存,然后在析构函数里用 delete 释放内存。最初写这个类的时候当然不难做,你会记得最后对在所有构造函数里分配了内存的所有成员使用 delete。 然而,这个类经过维护、升级后,情况就会变得困难了,因为对类的代码进行修改的程序员不一定就是最早写这个类的人。而增加一个指针成员意味着几乎都要进行下面的工作:
2014-12-28 20:18:26 3311
原创 条款 12: 尽量使用初始化而不要在构造函数里赋值
看这样一个模板,它生成的类使得一个名字和一个 T 类型的对象的指针关联起来。templateclass NamedPtr {public:NamedPtr(const string& initName, T *initPtr);...private:string name;T *ptr;};因为有指针成员的对象在进行拷贝和赋值操作
2014-12-27 22:55:19 2165
原创 尽可能使用 const
使用 const 的好处在于它允许指定一种语意上的约束——某种对象不能被修改——编译器具体来实施这种约束。通过 const,你可以通知编译器和其他程序员某个值要保持不变。只要是这种情况,你就要明确地使用 const ,因为这样做就可以借助编译器的帮助确保这种约束不被破坏。 对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为const,或二者同时指定为 con
2014-12-27 20:26:21 501
原创 条款 22: 尽量用“传引用”而不用“传值”
除非明确指定,函数的形参总是通过“实参的拷贝”来初始化的,函数的调用者得到的也是函数返回值的拷贝。用传值来传递对象,会调用大量的构造函数和析构函数,效率低下。所以,为避免这种潜在的昂贵的开销,就不要通过值来传递对象,而要通过引用。 const Student& returnStudent(const Student& s) { return s;} 这会非常高效:没有构
2014-12-27 20:00:14 758
转载 深入分析C++引用
关于引用和指针的区别的文章很多很多,但是总是找不到他们的根本区别,偶然在codeproject上看到这篇文章,觉得讲的挺好的,所以翻译了下,希望对大家有帮助。原文地址: http://www.codeproject.com/KB/cpp/References_in_c__.aspx 引言 我选择写 C++ 中的引用是因为我感觉大多数人误解了引用。而我之所以有这个感受是
2014-12-27 19:42:43 591 1
原创 条款 23: 必须返回一个对象时不要试图返回一个引用
一旦程序员抓住了“传值”在效率上的把柄(参见条款 22) ,他们会变得十分极端,恨不得挖出每一个隐藏在程序中的传值操作。岂不知,在他们不懈地追求纯粹的“传引用”的过程中,他们会不可避免地犯另一个严重的错误:传递一个并不存在的对象的引用。这就不是好事了。 class Rational {public:Rational(int numerator = 0, int denomin
2014-12-27 19:18:03 521
原创 条款 31: 千万不要返回局部对象的引用,也不要返回函数内部用 new 初始化的 指针的引用
返回一个局部对象的引用。它的问题在于,局部对象----- 顾名思义---- 仅仅是局部的。也就是说,局部对象是在被定义时创建,在离开生命空间时被销毁的。所谓生命空间,是指它们所在的函数体。当函数返回时,程序的控制离开了这个空间,所以函数内部所在的局部对象被自动销毁。因此,如果返回局部对象的引用,那个局部对象其实已经在函数调用者使用它之前被销毁了。 当想提高程序的效率而使函数的
2014-12-27 18:56:27 1017
原创 解析局部对象与临时对象
没有名字的对象就是临时对象,它存在于完整的表达式的生存其间。也就是说,当表达式计算结束后就会被释放。一个例外是,当临时对象被引用时,它的生存期将延长到与这个引用的生存期一样长。局部对象就是可见区域在一个函数范围的对象。局部对象有两种,静态局部对象的生存期起于所在函数第一次被调用,结束于main()函数退出之后。自动局部对象生存期起于所在函数每一次被调用,结束于函数返回。A fun(
2014-12-27 18:47:32 977
转载 机器学习的各种资源链接
(1) 如何入门 (每个人都会有自己的入门方式,以下资源仅供参考) |-- 通用 |-- 公开课资源 |-- coursera.org. 可以说是目前世界上最棒的公开课网站。 |-- 机器学习入门 |-- 书籍推荐 |-- 转自水木insomnia的机器学习书单
2014-12-20 11:33:03 655
转载 人脸识别必读的N篇文章
人脸识别必读的N篇文章一.人脸检测/跟踪 人脸检测/跟踪的目的是在图像/视频中找到各个人脸所在的位置和大小;对于跟踪而言,还需要确定帧间不同人脸间的对应关系。 1.Robust Real-time Object Detection. Paul Viola, Michael Jones. IJCV 2004. 入选理由: Viola的人脸检测工作使得人脸检测真
2014-12-19 21:26:04 671
转载 计算机视觉、机器学习相关领域论文和源代码大集合--持续更新……
计算机视觉、机器学习相关领域论文和源代码大集合--持续更新……zouxy09@qq.comhttp://blog.csdn.net/zouxy09 注:下面有project网站的大部分都有paper和相应的code。Code一般是C/C++或者Matlab代码。最近一次更新:2013-3-17一、特征提取Feature Extractio
2014-12-19 19:50:35 631
转载 机器学习算法中文视频教程
机器学习算法中文视频教程zouxy09@qq.comhttp://blog.csdn.net/zouxy09 在网上狂搜ReproducingKernel Hilbert Space的时候,找到了一个好东西。这个是李政軒Cheng-Hsuan Li的关于机器学习一些算法的中文视频教程。感觉讲得很好。这里非常感谢他的分享:http://www.power
2014-12-19 19:47:00 1489 2
原创 条款 14: 确定基类有虚析构函数
class EnemyTarget {public:EnemyTarget() { ++numTargets; }EnemyTarget(const EnemyTarget&) { ++numTargets; }~EnemyTarget() { --numTargets; }static size_t numberOfTargets(){ return numTargets
2014-12-17 16:24:51 493
原创 条款 36: 区分接口继承和实现继承
(公有)继承的概念看起来很简单,进一步分析,会发现它由两个可分的部分组成:函数接口的继承和函数实现的继承.class Shape {public:virtual void draw() const = 0;virtual void error(const string& msg);int objectID() const;};class Rectangle: public Sha
2014-12-17 13:56:55 484
原创 条款 11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符
// 一个很简单的 String 类class String {public:String(const char *value);~String(); // 没有拷贝构造函数和 operator=private:char *data;};String::String(const char *value){if (value) {data = ne
2014-12-17 10:52:58 737
原创 条款 27: 如果不想使用隐式生成的函数就要显式地禁止它
假设想写一个类模板 Array,它所生成的类除了可以进行上下限检查外,其它行为和 C++标准数组一样。设计中面临的一个问题是怎么禁止掉 Array 对象之间的赋值操作,因为对标准 C++数组来说赋值是不合法的:double values1[10];double values2[10];values1 = values2; // 错误! 对很多函数来说,这不是
2014-12-17 10:34:00 557
原创 初始化类中的const 类型 和 引用类型
正确的初始化是通过构造函数的初始化列表来进行,如: class Test { public: const int MY_MASK; Test() : MY_MASK(0xff) {} }; 如果不是在初始化列表中对 const 常量进行初始化,而是在构造函数中对其赋值的话,是不能成功的。很简单的道理:不能给 const 成员赋值。同样的道理,如
2014-12-17 10:00:28 696
原创 条款 45: 弄清 C++在幕后为你所写、所调用的函数
如果你没有声明下列函数,体贴的编译器会声明它自己的版本。这些函数是:一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符。另外,如果你没有声明任何构造函数,它也将为你声明一个缺省构造函数。所有这些函数都是公有的。class Empty {public:Empty(); // 缺省构造函数Empty(const Empty& rhs); // 拷贝构造函数~Empty();
2014-12-17 09:23:01 559
原创 拷贝构造函数,构造函数
当基类中“显示定义了拷贝构造函数和赋值操作符时”当派生类中“显示定义了拷贝构造函数和赋值操作符时”如果派生类中的拷贝和赋值构造函数中没有“显示指定基类的拷贝和赋值构造函数”,即:派生类只是把自己的成员进行了赋值这时需要手动调用基类的拷贝构造函数和赋值构造函数才行,基类的构造函数会自动调用的#include using namespace std;class A{
2014-12-11 11:05:05 526
原创 条款五 对定制的[型别转换函数保持警觉]
对于自己定义的型别,我们可以选择是否要提供某些函数,供编译器来作为隐式型别转换之用。 两种函数允许执行这样的转化:1.单自变量的constructors 和 隐式型别转换操作符。所谓,单自变量的constructors就是指能够以单一自变量成功调用的constructor.。如此的constructor可能拥有单一参数,也可能拥有多个参数,并且除了第一个参数都有缺省值。
2014-12-08 10:47:28 501
原创 error C2664: “countChar”: 不能将参数 1 从“char [20]”转换为“std::string &”
size_t countChar( string& str,char ch){ cout<<str; return 1;}int main(void){ char buffer[20]; char c; cin>>c>>buffer; cout<<countChar(buffer,c);}编译后就会出现该错误:原因:类型转换失败,参数类型转换,不能讲s
2014-12-08 10:12:25 1773
原创 条款19 了解临时对象的来源
只要你产生一个no-heap-object而没有为它命名,便产生了一个临时对象。 临时对象的产生途径:1.当隐式型别转换被施行起来以求函数能够调用成功。2.当函数返回对象的时候。 1.当隐式型别转换被施行起来以求函数能够调用成功size_t countChar(const string& str,char ch){ cout
2014-12-08 09:46:18 764
原创 _BLOCK_TYPE_IS_VALID
出现错误如:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)可能是类忘了定义拷贝构造函数,特别是含有指针成员的时候,即使指针成员是一般类型,默认的拷贝构造函数似乎能很好的完成任务,但是还是可能出现默名奇妙的错误,我不理解,所以,一定要定义拷贝构造函数。举例见博客:
2014-12-04 10:36:40 821
原创 类一定要定义拷贝构造函数,特别是在类成员含有指针的情况(不论指针是何种类型),安全!!!
举例说明一个未定义拷贝构造函数,产生的非常诡异的现象using namespace std;class people {private:char *name;int age;public:people(char *namestr,int i);/*people( const people& temp);*/~people();char *getname(
2014-12-04 10:20:17 2791
原创 常成员函数只能调用常成员函数 常对象智能调用常成员函数
class A{public: void print()const{ coutvoid test() { print();}void test1() const {print();} };int main(int argc, char* argv[]){ A a;a.print();a.test();a.test1(); return
2014-12-04 08:54:50 5318
转载 引用传回左值,左值可赋值,右值不可赋值
函数返回值分为:值,引用,指针三种。引用是c没有而c++有的,并且因为引用是左值实现了运算符连续运算的基础,而值和引用都不可以。下面我们就来看一下这三种返回方式的各自的特点:1、返回值[cpp] view plaincopyint test1() { int a = 1; retur a;
2014-12-03 12:47:10 910
原创 迭代器思想总结
advanced()对于不同的迭代器类型(类型)有不同的实现方式,类似于重载的概念,(不同的参数对应于不同的实现)。所以,可以使用重载,可以为每个迭代器定义一个类型标志符,使用类型标志符来促成重载。具体实现如下:首先必须定义五种迭代器的类型标志符: //5个迭代器类型 struct input_iterator_tag{}; struct output_ite
2014-12-03 09:40:46 696
转载 STL源码学习之迭代器
1、迭代器是什么?为什么要引入迭代器? STL是将容器与算法分离开的,我们用到的类模板和函数模板即是用于实现这两个东西,其中类模板用于实现容器,函数模板用于实现算法,在使用的时候需要一个将两者联系起来的东西,这个东西就是迭代器。例如段代码1所示:算法find 需要访问容器ivec中的每一个元素之后才能确定该容器中是否有目标元素10,在这里find需要使用了类型为vector
2014-12-03 09:32:41 582
machine learining Dimensionality Reduction (Week 8) exercise
2015-04-22
machine learning Regularization (Week 3) exercise
2015-04-20
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人