上一页 1 ··· 27 28 29 30 31 32 33 34 35 ··· 58 下一页
  2014年1月20日
摘要: 1、copy构造和copy赋值,我们称为copy方法。当我们声明自己的copy方法时,就意味着,告诉编译器,我自己定义copy构造和copy赋值,不要你自动生成。这种情况下,自己要保证复制对象的时候,不要忘记每一个成分。2、开始定义一个类的时候,在copy构造我们会初始化每一个字段,在copy赋值我们会为每个字段赋值,不会出错。后来,当我们在类中增加一个字段,很可能会忘记初始化这个字段,或者为它赋值。这种情况,要特别注意。3、当出现继承的时候,存在潜在的问题。子类会继承父类的字段,即使是private字段也继承下来,只不过不能访问。这种情况下,不要忘记父类中的字段。4、copy构造的时候,在初 阅读全文
posted @ 2014-01-20 21:02 Andy Niu 阅读(273) 评论(0) 推荐(0)
摘要: 1、自我赋值,看起来愚蠢,但是却合法。有些自我赋值一眼就可看出来。有些自我赋值是潜在的。比如:a[i] = a[j]; *px = *py; 甚至不同类型的指针,都指向同一个地址,也是自我赋值,这一类自我赋值,很难识别,因此对自我赋值要有一定的防范。2、对于资源管理类auto_ptr和shared_ptr,自我赋值是安全的。如果自行管理资源,比如Widget中有个Bitmap* pb;copy赋值如下:1 Widget& Widget::operator=(const Widget& rhs)2 {3 delete pb;4 pb = new Bitmap(*(rhs.pb)) 阅读全文
posted @ 2014-01-20 20:35 Andy Niu 阅读(1252) 评论(0) 推荐(0)
摘要: 1、swap交换对象值,std提供了实现方法模版的实现,它的实现是交换对象值。 1 namespace std 2 { 3 template 4 void swap(T& a,T& b) 5 { 6 T temp(a); 7 a = b; 8 b = a; 9 }10 }2、考虑下面的情况下,资源管理类Widget,内部只有一个指针WidgetImpl,该指针指向一个对象,这个对象中包含真正数据。对这种资源管理类执行swap,如果调用std中的swap,有哪些动作?对于Widget,copy构造一次,copy赋值两次,同时对于WidgetImpl,copy构造一次,cop... 阅读全文
posted @ 2014-01-20 19:56 Andy Niu 阅读(635) 评论(0) 推荐(0)
  2014年1月17日
摘要: 1、引用计数字段不能放在资源管理类中。我们的解决办法是,把引用计数和资源绑在一起,进行二次封装。但是这样存在一个大问题,不同类型的资源管理类不能兼容。也就是说,shared_ptr不能赋值给shared_ptr。2、你可能会想,使用模版成员方法去解决,但是这里有个问题。因为进行了两次封装,u_ptr的类型还是不一样,也不能赋值。你可能会想,我在u_ptr中也建立模版成员方法,这也是错的。思考下,我们要保证,资源管理类指向同一个u_ptr,对u_ptr进行拷贝,那么资源管理类就不是指向同一个u_ptr了,这显然是错的。3、有没有其它的办法呢? 问题的关键是,进行了两次封装。不进行两次封装就好了. 阅读全文
posted @ 2014-01-17 21:22 Andy Niu 阅读(843) 评论(0) 推荐(0)
摘要: 1、shared_ptr解决什么问题? auto_ptr有个局限,拥有权转移。这往往不符合我们的需求,有时候我们期望,多个资源管理对象可以共享一个资源,当引用计数为0的时候,执行delete。shared_ptr就是为了解决这个问题。2、shared_ptr怎么解决这个问题?和auto_ptr类似,除此之外,还有几点需要注意:3、增加一个字段为引用计数,当引用计数为0的时候,执行delete。引用计数字段不能放在资源管理类中,为什么? 假设放到资源管理类中,每个资源管理对象都有一个refCount字段,共享一个资源的资源管理对象的refCount取值一样,但是怎么保持一致呢?因为这些对象之.. 阅读全文
posted @ 2014-01-17 19:05 Andy Niu 阅读(1751) 评论(0) 推荐(0)
摘要: 1、auto_ptr解决什么问题? 在堆上获取的资源,客户可能会忘记delete,或者由于异常没有执行到delete,导致资源泄漏。在栈上分配的对象,有个特点,不论出现什么情况,超出作用域后,都将调用析构方法。根据这个特点,可以使用栈上的对象管理指针,析构的时候执行delete,确保一定释放资源。2、auto_ptr就是解决这个问题的,auto_ptr就是个资源管理类,它的特点是拥有权转移。3、考虑,如果让我来设计auto_ptr,我该怎么做? auto_ptr是个资源管理类,对指针封装。有几点需要注意: a、可以对不同类型的指针进行封装,因此需要一个模板类。 b、copy构造,cop... 阅读全文
posted @ 2014-01-17 18:40 Andy Niu 阅读(835) 评论(0) 推荐(0)
  2014年1月16日
摘要: 1、绝不在构造和析构过程中调用virtual方法,为啥? 原因很简单,对于前者,这种情况下,子类专有成分还没有构造,对于后者,子类专有成分已经销毁,因此调用的并不是子类重写的方法,这不是程序员所期望的。2、在构造方法和析构方法中,直接调用virtual方法,很容易识别。还有一种情况要注意,那就是间接调用。比如:构造方法调用init方法,而init方法调用virtual方法。3、在构造过程中,不能使用virtual从上到下调用,哪有什么办法弥补呢? 可以将子类必要的信息向上传递给父类构造方法。 阅读全文
posted @ 2014-01-16 21:11 Andy Niu 阅读(270) 评论(0) 推荐(0)
摘要: 1、考虑一个类Widget,析构方法抛出异常,一个集合中包含10个Widget对象,集合离开作用域,逆序撤销集合里的对象,最后一个抛出异常,倒数第二个抛出异常,问题出现了,这种情况下,要么导致程序结束,要么导致不明确行为。2、因此,绝不能在析构方法中抛出异常。考虑,数据库连接类DBConn,用户可能会忘记关闭连接,因此在DBConn的析构方法中,执行Close方法。那么问题来了,close方法可能会抛出异常,怎么办? a、在析构方法中,捕获异常,结束程序,这种方法可用性太差。 b、在析构方法中,捕获异常,吞下异常,这种方法忽略错误,程序继续运行,接下来可能会导致不明确行为。3、上面两种解决.. 阅读全文
posted @ 2014-01-16 21:00 Andy Niu 阅读(291) 评论(0) 推荐(0)
摘要: 1、思考,对于C++,能不能在外部调用私有方法?2、在Java中,子类继承不能缩小父类成员的访问权限。因为在Java中,继承只是表示Is-A关系,因此,父类提供的接口,子类必须承诺仍然提供,不能缩小访问权限,但是可以放大权限。3、在C++中,继承不光表示Is-A关系,还可以表示根据某物实现出。因此,在C++中,子类可以放大或者缩小父类成员的访问权限。考虑,如果父类提供public virtual方法,子类重写为private virtual方法,我们知道,重写只不过是,子类整体拷贝父类的虚方法表,对于重写的方法偷梁换柱,替换为重写后的方法。在这种情况下,父类指针指向子类对象,父类指针通过调用p 阅读全文
posted @ 2014-01-16 20:34 Andy Niu 阅读(4841) 评论(0) 推荐(1)
摘要: 1、考虑下面的需要,需要一个工厂方法。工厂方法的规则是:在堆上分配一个子类对象,并返回父类指针。使用完毕,delete父类指针。如果父类的析构方法不是virtual,将直接调用父类的析构方法,导致局部销毁的对象,父类成分销毁了,子类成分没有销毁。2、如果类中有virtual方法,意味着面向抽象编程,也就是会有父类指针指向子类对象,因此这种情况下,必定需要一个virtual析构方法。3、如果类中没有virtual方法,为了节省空间,析构方法是non-virtual方法。也就意味着,这个类不作为父类。如果你继承这样的类,就会导致上面的局部销毁对象。Java中有final,C#中sealed,禁止继 阅读全文
posted @ 2014-01-16 19:53 Andy Niu 阅读(367) 评论(0) 推荐(0)
上一页 1 ··· 27 28 29 30 31 32 33 34 35 ··· 58 下一页