复制构造函数与赋值运算符(VC与gcc)
对于下面的程序:
View Code
#include <iostream>
#include <string>
using std::string;
//using std::size_t;
using std::endl;
using std::cout;
class Item_base{
public:
Item_base(const string &book="",double sales_price=0.0):
isbn(book),price(sales_price){
cout<<"base:constructor"<<endl;
}
string book()const {return isbn;}
virtual double net_price(size_t n)const
{
return n*price;
}
Item_base(const Item_base&ib):isbn(ib.isbn),price(ib.price){
cout<<"base:copy constructor"<<endl;
}
Item_base& operator=(const Item_base&rhs){
if(this != &rhs){
isbn=rhs.isbn;
price=rhs.price;
}
cout<<"base:assign"<<endl;
return *this;
}
virtual ~Item_base(){
cout<<"base:destructor"<<endl;
}
private:
string isbn;
protected:
double price;
};
class Bulk_item:public Item_base {
public:
Bulk_item(const string &book="",double sales_price=0.0,size_t qty=0,double disc_rate=0.0):
Item_base(book,sales_price),min_qty(qty),discount(disc_rate){
cout<<"bulk:constructor"<<endl;
}
double net_price(size_t cnt)const{
if(cnt>=min_qty)
return cnt*(1-discount)*price;
else
return cnt*price;
}
Bulk_item(const Bulk_item& bi):Item_base(bi),min_qty(bi.min_qty),discount(bi.discount){
cout<<"bulk:copy constructor"<<endl;
}
Bulk_item& operator=(const Bulk_item&rhs)
{
if(this !=&rhs){
Item_base::operator=(rhs);
min_qty=rhs.min_qty;
discount=rhs.discount;
}
cout<<"bulk:assign"<<endl;
return *this;
}
~Bulk_item()
{
cout<<"bulk:destructor"<<endl;
}
private:
size_t min_qty;
double discount;
};
class Lds_item:public Item_base {
public:
Lds_item(const string &book="",double sales_price=0.0,size_t qty=0,double disc_rate=0.0):
Item_base(book,sales_price),max_qty(qty),discount(disc_rate){
cout<<"lds:constructor"<<endl;
}
double net_price(size_t cnt)const{
if(cnt<=max_qty)
return cnt*(1-discount)*price;
else
return cnt*price-max_qty*discount*price;
}
Lds_item(const Lds_item& li):Item_base(li),max_qty(li.max_qty),discount(li.discount){
cout<<"lds:copy constructor"<<endl;
}
Lds_item& operator=(const Lds_item&rhs){
if(this !=&rhs){
Item_base::operator=(rhs);
max_qty=rhs.max_qty;
discount=rhs.discount;
}
cout<<"lds:assign"<<endl;
return *this;
}
~Lds_item(){
cout<<"lds:destructor"<<endl;
}
private:
size_t max_qty;
double discount;
};
void func1(Item_base obj)
{
cout<<"func1"<<endl;
}
void func2(Item_base& obj){
cout<<"func2"<<endl;
}
Item_base func3(){
cout<<"func3"<<endl;
Item_base obj;
return obj;
}
Bulk_item func4(){
cout<<"func4"<<endl;
Bulk_item obj;
return obj;
}
int main(){
Item_base obj;
cout<<"01========"<<endl;
func1(obj);
cout<<"02========"<<endl;
func2(obj);
cout<<"04========"<<endl;
obj=func3();
cout<<"05========"<<endl;
Item_base *p=new Item_base;
cout<<"06========"<<endl;
delete p;
cout<<"07========"<<endl;
Bulk_item bobj;
cout<<"08========"<<endl;
func1(bobj);
cout<<"09========"<<endl;
func2(bobj);
cout<<"10========"<<endl;
bobj=func4();
cout<<"11========"<<endl;
Bulk_item *q=new Bulk_item;
cout<<"12========"<<endl;
delete q;
cout<<"13========"<<endl;
return 0;
cout<<"14========"<<endl;
}
#include <string>
using std::string;
//using std::size_t;
using std::endl;
using std::cout;
class Item_base{
public:
Item_base(const string &book="",double sales_price=0.0):
isbn(book),price(sales_price){
cout<<"base:constructor"<<endl;
}
string book()const {return isbn;}
virtual double net_price(size_t n)const
{
return n*price;
}
Item_base(const Item_base&ib):isbn(ib.isbn),price(ib.price){
cout<<"base:copy constructor"<<endl;
}
Item_base& operator=(const Item_base&rhs){
if(this != &rhs){
isbn=rhs.isbn;
price=rhs.price;
}
cout<<"base:assign"<<endl;
return *this;
}
virtual ~Item_base(){
cout<<"base:destructor"<<endl;
}
private:
string isbn;
protected:
double price;
};
class Bulk_item:public Item_base {
public:
Bulk_item(const string &book="",double sales_price=0.0,size_t qty=0,double disc_rate=0.0):
Item_base(book,sales_price),min_qty(qty),discount(disc_rate){
cout<<"bulk:constructor"<<endl;
}
double net_price(size_t cnt)const{
if(cnt>=min_qty)
return cnt*(1-discount)*price;
else
return cnt*price;
}
Bulk_item(const Bulk_item& bi):Item_base(bi),min_qty(bi.min_qty),discount(bi.discount){
cout<<"bulk:copy constructor"<<endl;
}
Bulk_item& operator=(const Bulk_item&rhs)
{
if(this !=&rhs){
Item_base::operator=(rhs);
min_qty=rhs.min_qty;
discount=rhs.discount;
}
cout<<"bulk:assign"<<endl;
return *this;
}
~Bulk_item()
{
cout<<"bulk:destructor"<<endl;
}
private:
size_t min_qty;
double discount;
};
class Lds_item:public Item_base {
public:
Lds_item(const string &book="",double sales_price=0.0,size_t qty=0,double disc_rate=0.0):
Item_base(book,sales_price),max_qty(qty),discount(disc_rate){
cout<<"lds:constructor"<<endl;
}
double net_price(size_t cnt)const{
if(cnt<=max_qty)
return cnt*(1-discount)*price;
else
return cnt*price-max_qty*discount*price;
}
Lds_item(const Lds_item& li):Item_base(li),max_qty(li.max_qty),discount(li.discount){
cout<<"lds:copy constructor"<<endl;
}
Lds_item& operator=(const Lds_item&rhs){
if(this !=&rhs){
Item_base::operator=(rhs);
max_qty=rhs.max_qty;
discount=rhs.discount;
}
cout<<"lds:assign"<<endl;
return *this;
}
~Lds_item(){
cout<<"lds:destructor"<<endl;
}
private:
size_t max_qty;
double discount;
};
void func1(Item_base obj)
{
cout<<"func1"<<endl;
}
void func2(Item_base& obj){
cout<<"func2"<<endl;
}
Item_base func3(){
cout<<"func3"<<endl;
Item_base obj;
return obj;
}
Bulk_item func4(){
cout<<"func4"<<endl;
Bulk_item obj;
return obj;
}
int main(){
Item_base obj;
cout<<"01========"<<endl;
func1(obj);
cout<<"02========"<<endl;
func2(obj);
cout<<"04========"<<endl;
obj=func3();
cout<<"05========"<<endl;
Item_base *p=new Item_base;
cout<<"06========"<<endl;
delete p;
cout<<"07========"<<endl;
Bulk_item bobj;
cout<<"08========"<<endl;
func1(bobj);
cout<<"09========"<<endl;
func2(bobj);
cout<<"10========"<<endl;
bobj=func4();
cout<<"11========"<<endl;
Bulk_item *q=new Bulk_item;
cout<<"12========"<<endl;
delete q;
cout<<"13========"<<endl;
return 0;
cout<<"14========"<<endl;
}
这是C++primer 第4版的习题15.20,答案给出的解释是:
但是我在实际运行程序的时候,发现对于func3的执行方式,GCC和VC有不同的处理:
如上图中,从左到右分别代表:VS2008 Debug,GCC -O0(不使用优化),VS2008 Release
从图中红色的1和2两处可以看到三种情况的下的处理的不同:
VS2008 在Debug情况下处理的方式和C++primer的答案给出的结果是一致的。而g++和VS2008 Release版本是进行了优化。
对于func3函数,声明了一个局部的Item_base的对象,返回值是Item_base类型的对象。没有进行优化的方式下,按照C++标准进行处理:先将声明的局部变量进行调用复制构造函数生成一个副本,在return的时候,先调用局部变量的析构函数,然后调用赋值操作符将副本赋值给obj(bobj)对象,然后调用析构函数释放掉副本。而在优化的情况下是省略了调用复制构造函数生成副本 的情况。