文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>复制构造,赋值操作符,const重要性

复制构造,赋值操作符,const重要性

时间:2010-09-09  来源:Pro.Charm

原文地址:http://www.coderess.com/?p=55

什么是复制构造?

复制构造是类或结构体的一种特殊的拷贝已存在实例构造函数。根据C++标准,复制构造函数可以有以下几种形式:

  MyClass( const MyClass& other );  MyClass( MyClass& other );  MyClass( volatile const MyClass& other );  MyClass( volatile MyClass& other );

注意不要写成以下形式,尽管它们也能够实现同样的事:

  MyClass( MyClass* other );  MyClass( const MyClass* other );  MyClass( MyClass other );

 

什么时候需要写自己的复制构造函数?

首先,你需要明白假如你没声明一个复制构造函数,编译器会给你提供默认的构造函数。这个默认的构造函数能智能地(member-wise)复制源对象,比如这个类:

class MyClass { int x; char c; std::string s; };

编译器提供的默认构造函数相当以下功能:

 MyClass::MyClass( const MyClass& other ) :     x( other.x ), c( other.c ), s( other.s )  {}

在很多情况下,这是足够的。然而,有些情景下member-wise的拷贝方式是不够的。尤为常见的原因是默认的复制构造会产生野指针(raw pointer),这个时候你需要深复制指针成员,这是当你不是想复制指针本身,而是想复制指针指向的内容。为什么需要深复制?这是因为通常一个实例拥有指针,同时在某些时候它也负责删除这个指针,比如析构函数发生的前一刻。假如两个对象都析构调用 delete 函数删除非空指针成员,会导致堆栈溢出。

 

使用编译器提供的默认复制构造函数,很少情况不会出现野指针,因此默认构造函数是不足够的。你也可以使用引用计数。比如boost::shared_ptr<>。

正确使用const  (Const correctness)

当通过引用的方式传递参数给函数或者构造对象时,要很小心地正确使用const。仅仅当函数会修改传递的函数才使用non-canst引用,否则就应该使用const引用。

为什么强调要这样? 这是一个C++标注的小条款:non-const 引用不能绑定到临时对象,临时对象时一个没有变量名的实例,比如:

std::string( "Hello world" );

是一个临时对象,因为没有变量名。下面一个不是临时对象:

std::string s( "Hello world" );

 

这个实用的提醒有什么用?请看下面:

// Improperly declared function:  parameter should be const reference:  void print_me_bad( std::string& s ) {      std::cout << s << std::endl;  }  // Properly declared function: function has no intent to modify s:  void print_me_good( const std::string& s ) {      std::cout << s << std::endl;  }  std::string hello( "Hello" );  print_me_bad( hello );  // Compiles ok; hello is not a temporary  print_me_bad( std::string( "World" ) );  // Compile error; temporary object  print_me_bad( "!" ); // Compile error; compiler wants to construct temporary                       // std::string from const char*  print_me_good( hello ); // Compiles ok  print_me_good( std::string( "World" ) ); // Compiles ok  print_me_good( "!" ); // Compiles ok 

 

很多STL的容器和算法都要求一个对象时可拷贝的。通常,这意味着你需要有实用const传引用的复制构造函数。 (最近一个搞了很久的错误就是这个问题,所以觉得这篇文章很好,就翻译过来分享了)

插曲(译者经历):

我在使用list的时候,用到了replace泛型算法:

template < class ForwardIterator, class T >  void replace ( ForwardIterator first, ForwardIterator last,  const T& old_value, const T& new_value )
{  
for (; first != last; ++first)    
if (*first == old_value) *first=new_value;
}

很明显这个算法要求对象具有 == 操作符来比较。我也为对象重载了 == 操作符:

查看完整文章:http://www.coderess.com/?p=55#more-55

相关阅读 更多 +
排行榜 更多 +
边境检察最后区域手机版下载

边境检察最后区域手机版下载

角色扮演 下载
酋长你别跑手游下载

酋长你别跑手游下载

休闲益智 下载
心动漫画app下载官方版

心动漫画app下载官方版

浏览阅读 下载