来,复习一下运算符重载 [Easy Questions]

yeahchang 2004-07-01 03:04:26
(1)劳驾各位看一下下面的code是否正确:
class myclass
{
public:
//无返回值:
//operator int();//myclass->int转换运算符
myclass();
myclass(int,int);
myclass(int);
~myclass();
myclass(myclass&);

bool operator==(const myclass&);
myclass& operator=(const myclass&);
myclass operator+(const myclass&);
myclass operator-(const myclass&);
myclass& operator++();
myclass myclass::operator++(int);

int readi()const {return m_num;}
int readp()const {return *p_num;}

private:
int m_num;
int *p_num;

};

myclass::myclass():
m_num(0)
{
std::cout<<"调用缺省构造函数。\n";
if(p_num=new int)
{
*p_num=0;
}
else
{
myclass::~myclass();
}
}
myclass::myclass(int new_num,int new_p_num):
m_num(new_num)
{
std::cout<<"调用构造函数(int,int)。\n";
if(p_num=new int)
{
*p_num=new_p_num;
}
else
{
myclass::~myclass();
}
}
myclass::myclass(int new_num):
m_num(new_num)
{
std::cout<<"调用构造函数(int)/int->myclass转换。\n";
if(p_num=new int)
{
*p_num=0;
}
else
{
myclass::~myclass();
}
}
myclass::~myclass()
{
std::cout<<"调用析构函数。\n";
m_num=0;
if(p_num)
{
delete p_num;
p_num=NULL;
}
}
myclass::myclass(myclass& rhs):
m_num(rhs.readi())
{
std::cout<<"调用复制构造函数。\n";
if(p_num=new int)
{
*p_num=rhs.readp();
}
else
{
myclass::~myclass();
}
}


bool myclass::operator ==(const myclass& rhs)
{
std::cout<<"调用运算符重载(operator==)运算(符)。\n";
if((m_num==rhs.readi())&&(*p_num==rhs.readp()))
{
return true;
}
else
{
return false;
}
}
myclass& myclass::operator=(const myclass& rhs)
{
std::cout<<"调用运算符重载(赋值)运算(符)。\n";
if(*this==rhs)
{

}
else
{
m_num=rhs.readi();
*p_num=rhs.readp();

}
return *this;
}
myclass myclass::operator +(const myclass& rhs)
{
std::cout<<"调用运算符重载(operator+)运算(符)。\n";
return myclass((m_num+rhs.readi()),((*p_num)+rhs.readp()));
}
myclass myclass::operator -(const myclass& rhs)
{
std::cout<<"调用运算符重载(operator-)运算(符)。\n";
return myclass((m_num-rhs.readi()),((*p_num)-rhs.readp()));
}
myclass& myclass::operator++()
{
std::cout<<"调用operator++(Perfix)(重载运算符)。\n";
++m_num;
return *this;
}
myclass myclass::operator++(int) //postfix
{
std::cout<<"调用operator++(Postfix)(重载运算符)。\n";
return myclass(m_num++); //需要这个构造函数
}

(2)为什么将myclass operator+(const myclass&)改为myclass& operator+(const myclass&),VC 7.1会报warning C4172: 返回局部变量或临时变量的地址?能否阐述一下机理?

(3)为什么在类中加入operator int(){std::cout<<"调用myclass->int转换运算(符)。\n"; return int(m_num);}后程序会发生崩溃??能否阐述一下机理?

分不够可以加!!
...全文
597 37 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
kaphoon 2004-07-15
  • 打赏
  • 举报
回复
#include<iostream>
#include<new> //bad_alloc

class myclass
{
public:


myclass();
myclass(int,int);
myclass(int);
~myclass();
myclass(const myclass&);//通常为const引用

bool operator==(const myclass&);
myclass& operator=(const myclass&);
myclass operator+(const myclass&);
myclass operator-(const myclass&);
myclass& operator++();
myclass myclass::operator++(int);

int readi()const {return m_num;}
int readp()const {return *p_num;}
operator int () const;

private:
int m_num;
int *p_num;

};

/*个人觉得这种在构造函数中检查,没有必要,
你可以直接p_num = new int;然后在用到myclass的构造函数时,
再用try-catch捕作bad_alloc,这样的解决方案更实际,

如果是你说的那种”好运“那么可以考虑
try{
first = new int(1);
second = new int(2);
third = new int(3);
}catch(std::bad_alloc& e)
{
if(first) {delete first;first= NULL;}
if(second) {delete second;second = NULL;}
if(third) { delete third;third = NULL}
throw; //再抛出错误给用户
}

*/

myclass::myclass():
m_num(0)
{
std::cout<<"调用缺省构造函数。\n";

p_num = new int;


}
myclass::myclass(int new_num,int new_p_num):
m_num(new_num)
{
std::cout<<"调用构造函数(int,int)。\n";

p_num = new int(new_p_num);

}
myclass::myclass(int new_num):
m_num(new_num)
{
std::cout<<"调用构造函数(int)/int->myclass转换。\n";

p_num = new int;

}

myclass::~myclass()
{
std::cout<<"调用析构函数。\n";
m_num=0;
if(p_num)
{
delete p_num;
p_num=NULL;
}
}
myclass::myclass(const myclass& rhs):
m_num(rhs.readi())
{
std::cout<<"调用复制构造函数。\n";

p_num = new int(rhs.readp());

}


bool myclass::operator ==(const myclass& rhs)
{
std::cout<<"调用运算符重载(operator==)运算(符)。\n";
if((m_num==rhs.readi())&&(*p_num==rhs.readp()))
{
return true;
}
else
{
return false;
}
}

//是this!=&rhs,不是*this!=rhs,它们之间有不同的
myclass& myclass::operator=(const myclass& rhs)
{
std::cout<<"调用运算符重载(赋值)运算(符)。\n";
if(this!=&rhs)
{
m_num=rhs.readi();
*p_num=rhs.readp();

}
return *this;
}

//这么定义operator +不够好,你可以参见complex的实现
//通常都是先定义+=,然后在operator中调用operator +=
//而且operator +通常是协助函数,而不是成员函数
myclass myclass::operator +(const myclass& rhs)
{
std::cout<<"调用运算符重载(operator+)运算(符)。\n";
return myclass((m_num+rhs.readi()),((*p_num)+rhs.readp()));
//调用myclass(int,int)
}
myclass myclass::operator -(const myclass& rhs)
{
std::cout<<"调用运算符重载(operator-)运算(符)。\n";
return myclass((m_num-rhs.readi()),((*p_num)-rhs.readp()));
//调用myclass(int,int)
}
myclass& myclass::operator++()
{
std::cout<<"调用operator++(Perfix)(重载运算符)。\n";
++m_num;
return *this;
}
myclass myclass::operator++(int) //postfix
{
std::cout<<"调用operator++(Postfix)(重载运算符)。\n";
return myclass(m_num++); //需要这个构造函数
}
myclass::operator int ()const
{
std::cout<<"调用myclass->int转换运算(符)。\n"<<std::endl;
return m_num;
}


int main()
{
try{
myclass a(1);
myclass b(3);
myclass c ;
c = a+b ;
}catch(std::bad_alloc& e)
{
std::cout<<e.what()<<std::endl;
}
}
/*
好像不存在你说的不确定性,
不如你写个main,让我看一下,你的不确定
*/

/*
关于临时对象我再补充一下(摘自《TC++PL》一书):
除非一个临时对象被约束到某个引用(const引用),或者被用作命名对象的初始化。
(这时,临时对象将在它的引用或者命名变量离开作用域时销毁
否则,它将总在建立它的那个完整表达式(不是其他表达式的子表达式)结束时销毁
void f(string& s1,string& s2,string& s3)
{
const char* cs = (s1+s2).c_str();//cs指向已经释放掉的存储
cout<<cs;
if(strlen(cs = (s2+s3).c_str())<8&&cs[0]=='a')
{
//use cs
}
} */
peter9606 2004-07-05
  • 打赏
  • 举报
回复
嘿嘿 那就结贴吧:)
yeahchang 2004-07-05
  • 打赏
  • 举报
回复
To peter9606(裴裴):
头好晕,先翻翻书再说。
谢谢您!

第三个问题如何解释??
没有operator int()时:
调用运算符重载(operator+)运算(符)。
调用构造函数(int,int)。
调用运算符重载(赋值)运算(符)。
调用运算符重载(operator==)运算(符)。
调用析构函数。

有operator int()时:
调用运算符重载(operator-)运算(符)。
调用构造函数(int,int)。
调用myclass->int转换运算(符)。
调用构造函数(int)/int->myclass转换。
调用析构函数。
调用运算符重载(赋值)运算(符)。
调用运算符重载(operator==)运算(符)。
调用析构函数。
peter9606 2004-07-03
  • 打赏
  • 举报
回复
不知道楼主满意了没有
peter9606 2004-07-02
  • 打赏
  • 举报
回复
To fireseed(奶油狗【对不起,我不是摩的!】)

楼主的意思 是让大虾们给微观分析(估计是汇编层面上) 一下的:)
fireseed 2004-07-02
  • 打赏
  • 举报
回复
int f(int a){return a;}

f(4);


参数int a是属于函数f的局部变量,生存期在函数体之内。

4是常量,将会被赋值给a

return a时,编译器会把a复制给接受返回值的变量,如果没有,return a没有意义。

peter9606 2004-07-02
  • 打赏
  • 举报
回复
我也不是很清楚
你还是问问版主吧

我来帮你up
yeahchang 2004-07-02
  • 打赏
  • 举报
回复
To peter9606(裴裴):
int f(int a){return a;}

f(4);
到底都作了什么?(能否微观上帮我顺一遍)
另:问题3如何解释:

没有operator int()时:
调用运算符重载(operator+)运算(符)。
调用构造函数(int,int)。
调用运算符重载(赋值)运算(符)。
调用运算符重载(operator==)运算(符)。
调用析构函数。

有operator int()时:
调用运算符重载(operator-)运算(符)。
调用构造函数(int,int)。
调用myclass->int转换运算(符)。
调用构造函数(int)/int->myclass转换。
调用析构函数。
调用运算符重载(赋值)运算(符)。
调用运算符重载(operator==)运算(符)。
调用析构函数。
peter9606 2004-07-02
  • 打赏
  • 举报
回复
To 楼主:


有中间变量,例如
int a(){}
int b(){a();}
那么在b()中有一个int类型的无名变量,由编译器维护
不同的编译器会产生不同的代码,不过原理都一样。
kaphoon 2004-07-02
  • 打赏
  • 举报
回复
不论成功不成功
系统都会自动调用
析构函数
kaphoon 2004-07-01
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;
class Test{
private:
int num;
public:
Test(int _num):num(_num){cout<<"constructor"<<endl;}
~Test(){cout<<"destructor"<<endl;}
void fun(){this->~Test();}

};
int main()
{
Test mytest(10);
mytest.fun();

}

yeahchang 2004-07-01
  • 打赏
  • 举报
回复
To kaphoon(齐柏林飞艇/去网络通信版玩玩):
明白了,是说:new不成功,系统会自动调用myclass::~myclass()吗??
yeahchang 2004-07-01
  • 打赏
  • 举报
回复
To kaphoon(齐柏林飞艇/去网络通信版玩玩):
你刚刚两次调用析构,一次是你在你的代码中显式地调用,还一次是系统自动调用??(具体些,没听懂,谢谢!!)

To peter9606(裴裴) :
int f(int a)
{
return a;
}
f(4);
=>
push 4
call f(41b14eh)//41b14eh->0x0041b14e(int)
add esp,4
kaphoon 2004-07-01
  • 打赏
  • 举报
回复
char* ptr = new char('h');
delete ptr;
delete ptr;//没问题
但是如果两次调用析构,就有问题
你刚刚两次调用析构,一次是你在你的代码中显式地调用,还一次是系统自动调用
peter9606 2004-07-01
  • 打赏
  • 举报
回复
存在一个拷贝构造的过程。
yeahchang 2004-07-01
  • 打赏
  • 举报
回复
To peter9606(裴裴) :
int f(int a)
{
return a;
}

f(4);
=>int::int(int&(4));//有这步吗???

To kaphoon(齐柏林飞艇/去网络通信版玩玩):
"多次delete没关系"是什么意思??您是不是说:用异常比直接调用myclass::~myclass()要好??

myclass1=myclass2+myclass3;
我认为:
1.myclass2. operator +(myclass3)
=>myclass myclass::operator +(const myclass& rhs)
{
std::cout<<"调用运算符重载(operator+)运算(符)。\n";
return myclass((m_num+rhs.readi()),((*p_num)+rhs.readp()));
}
(1)在栈中建立一个sizeof(myclass)的空间
(2)调用myclass((m_num+rhs.readi()),((*p_num)+rhs.readp()))以便在刚建好的空间中创建一个myclass匿名对象(记:temp1)
2.调用myclass1.operator=(temp1);
3.temp1没用了,销毁!
peter9606 2004-07-01
  • 打赏
  • 举报
回复
恩 我也明白了
赫赫 多谢。。。
嘿嘿 都是俺惹得祸 (是俺把老迈请来的 :))
kaphoon 2004-07-01
  • 打赏
  • 举报
回复
1.这个临时变量肯定有
2.什么叫'间接引用",没听过
3. peter9606(裴裴),你要我解释什么哦?
4.老迈啊,你害惨我拉~~~~~~~~~~~~~~~~~~
peter9606 2004-07-01
  • 打赏
  • 举报
回复
飞艇兄给详细解释一下拉

偶生性愚钝。。。。。。
kaphoon 2004-07-01
  • 打赏
  • 举报
回复
然后复制个一个临时变量(记为temp)???
》》》》》》》》》》》》》》》》》》》
会产生一个匿名的临时变量
加载更多回复(17)

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧