C++语言99个常见编程错误 常见错误47:赋值与初始化混淆

常见错误47:赋值与初始化混淆


  从技术视角看去,赋值和初始化没啥关系。它们之间泾渭分明,用在不同的场合。所谓初始化,
就是把一段生鲜存储(raw storage)变成一个对象的过程。对于一个class对象来说,这会
涵盖搭建一系列内部机能,以支持虚函数和虚基类,运行时类型信息以及其他类型相关信息。而
赋值,则是在一个有着合适定义的对象的某种状态上所做的一个变换,是该对象处于一个新
的状态,赋值操作不触及实现对象与类型相关的行为背后的内部机能。赋值操作也从来不会
在一段生鲜存储上实施。
  业内有个习惯,即,如果在某些场合下,复制构造语义是不二之选,那么复制赋值语义
则同样也是如影随形,反之亦然。

  参数的按值传递(时发生的复制操作)是由初始化操作,而非赋值操作完成的。


rawstorage.h
#ifndef RAWSTORAGE_H
#define RAWSTORAGE_H

#include <iterator>
#include <memory>

template <class Out, class T>
class raw_storage_iterator
    : public std::iterator<std::output_iterator_tag,void,void,void,void> {
  public:
    raw_storage_iterator& operator =( const T& element );
    explicit raw_storage_iterator( Out cur )
    	: cur_(cur) {}
    raw_storage_iterator& operator *()
    	{ return *this; }
    raw_storage_iterator& operator ++()
    	{ ++cur_; return *this; }
    raw_storage_iterator operator ++( int ) {
    	raw_storage_iterator tmp( *this );
    	++*this;
    	return tmp;
    }

  protected:
    Out cur_;
};

template <class Out, class T>
raw_storage_iterator<Out, T> &
raw_storage_iterator<Out,T>::operator =( const T &val ) {
    T *elem = &*cur_; // 取得指向element的指针
    new ( elem ) T(val); // placement 复制构造函数
    return *this;
}

#endif

rawstorage.cpp
#include "rawstorage.h"
#include <string>
#include <cstdlib>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <memory>

typedef std::string T;

struct X {
	X() : t_( new T("C++") ) {}
	~X() { delete t_; }
	X( const X &that ) : t_( new T(*that.t_) ) {}
    X &operator =( const X &rhs ) {
        if( this != &rhs )
            { delete t_; t_ = new T(*rhs.t_); }
        return *this;
    }
    const T &get_t() const { return *t_; }
    T *t_;
    //...
};

std::ostream &operator <<( std::ostream &o, const X &x )
	{ return o << *x.t_; }

int main() {
	X x;
	X *buf = (X *)std::malloc( sizeof(X) ); // raw storage...
	X &rx = *buf; // foul trickery...
	//rx = x; // probable error!
	
	const int N = 12;
	X a[N];
	X *ary = (X *)std::malloc( N*sizeof(X) );
	//std::copy( a, a+N, ary ); // 向一段生鲜内存赋值
	
	raw_storage_iterator<X *, X> ri( ary );
	std::copy( a, a+N, ri ); // works!
	
	std::copy( ary, ary+N, std::ostream_iterator<X>(std::cout,"\n") );

	return 0;
}


输出
C++
C++
C++
C++
C++
C++
C++
C++
C++
C++
C++
C++

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值