关于在重载赋值操作符,返回值为非 const对象引用值 的问题。
问题描述:
看到《C++ Primer Plus》12章,12.1.5-有关返回对象的说明的时候,见到里面关于 返回指向非const对象的引用 的问题,里面提到两种常见的返回非const对象的引用,其中就有重载赋值操作符。
原文大意:
String s1 ("Good stuff");
String s2,s3;
s3=s2=s1;
在这个例子中,返回类型不是const,因为方法operator=()返回一个指向s2的引用,可以对其修改。
============================分割线
我自己写了个例子,将重载赋值操作符的返回值 改为 const ,好像也可以,这是咋么回事啊??
代码如下:
头文件:
#ifndef STOCK_H_
#define STOCK_H_
#include <iostream>
class Stock
{
private:
int len; //新增加成员;
char *company;
int shares;
double shares_val;
double total_val;
void set_tot() {total_val=shares*shares_val;}
public:
Stock();
Stock(const char *co,int n=0,double pr=0.0);
Stock (const Stock & st); //新增加复制构造函数;
Stock (const char *s); //新增加转换函数;
const Stock & operator= (const Stock &st); //新增加重载赋值操作符;
friend std::ostream & operator<< (std::ostream &os,const Stock &st);
const Stock & operator= (const char *s);
~Stock();
void buy (int num,double price);
void sell (int num,double price);
void update (double price);
//void show() const;
const Stock & topval(const Stock &s) const;
};
#endif
========================分割线
实现文件:
#include <iostream>
#include "stock.h"
Stock::Stock()
{
len=8;
company=new char [len];
std::strcpy(company,"no name");
shares=0;
shares_val=0;
total_val=0;
}
Stock::Stock(const char *co,int n,double pr)
{
len=std::strlen(co);
company=new char [len+1];
std::strcpy(company,co);
if (n<0)
{
std::cerr<<"Number of shares can't be negative."
<<company<<"shares set to 0 .\n";
shares=0;
}
else
shares=n;
shares_val=pr;
set_tot();
}
Stock::Stock (const Stock & st)
{
delete [] company;
len=std::strlen(st.company);
company=new char [len+1];
std::strcpy(company,st.company);
shares=st.shares;
shares_val=st.shares_val;
total_val=st.total_val;
}
Stock::Stock (const char *s)
{
delete [] company;
len=std::strlen(s);
company=new char [len+1];
std::strcpy(company,s);
}
const Stock & Stock::operator= (const Stock &st)
{
if (this==&st)
return *this;
delete [] company;
len=std::strlen(st.company);
company=new char [len+1];
std::strcpy(company,st.company);
shares=st.shares;
shares_val=st.shares_val;
total_val=st.total_val;
return *this;
}
const Stock & Stock::operator= (const char *s)
{
delete [] company;
len=std::strlen(s);
company=new char [len+1];
std::strcpy(company,s);
return *this;
}
Stock::~Stock()
{
delete [] company;
}
void Stock::buy (int num,double price)
{
if (num<0)
{
std::cerr<<"Number of shares purchased can't be negative."
<<"Transaction is aborted.\n";
}
else
{
shares+=num;
shares_val=price;
set_tot();
}
}
void Stock::sell (int num,double price)
{
using std::cerr;
if (num<0)
{
cerr<<"Number of shares sold can't be negative. "
<<"Transaction is aborted.\n";
}
else if (num>shares)
{
cerr<<"You can't sell more than you have! "
<<"Transaction is aborted.\n";
}
else
{
shares-=num;
shares_val=price;
set_tot();
}
}
void Stock:: update (double price)
{
shares_val=price;
set_tot();
}
const Stock & Stock::topval(const Stock &s) const
{
if (s.total_val>total_val)
return s;
else
return *this;
}
std::ostream & operator<< (std::ostream &os,const Stock &st)
{
os<<"Company"<<st.company
<<" Shares: "<<st.shares<<std::endl
<<" Shares Price: $"<<st.shares_val
<<" Total Worth: $"<<st.total_val<<std::endl;
return os;
}
====================主函数
#include "stock.h"
#include <iostream>
#include <cstdlib>
int main()
{
using std::cout;
Stock s1("test",5000,32.0);
Stock s2("test-s2",1000,12.3);
Stock st2;
Stock st3;
st3=st2=s1;
st3=s2;
std::cout<<st2<<std::endl;
std::cout<<st3<<std::endl;
system("pause");
}
[解决办法]
重载操作符应当参照内建数据类型(如int)的行为。
返回string&与const string&是有本质区别的:前者为左值,后者为右值。
对于 = 操作符,因其运算顺序为从右至左,所以LZ的测试代码没有发现问题,但如果运算顺序为从左至右,那么区别马上体现,如下:
(s1=s2)=s3;
或
(s1=s2).update(15.5);
这时,你会发现编译通不过。