求指导

hahayezhe112 2010-08-21 04:19:58
一个人的思维经常会短路
最近2天老总出差,写了个大数类(以后可能会用的着吧),
在测试和内存管理遇到了问题,
比如+ - 里返回的引用是new出来的 应该怎么做才能做到让其自动释放
还有很多隐含的问题,希望达人有空看看,指导下
声明:(非炫耀)
头文件

#ifndef _Number_H_
#define _Number_H_
#include <iostream>
using namespace std;
#define UINT unsigned int
#define BYTE unsigned char
#define CBYTE const unsigned char
#define CUINT const unsigned int
class CNumber{
public:
CNumber(char *p=NULL);
~CNumber(){
MyNumber_delete();};
CNumber(CNumber&);
CNumber &operator=(CNumber&);
public:
bool operator<(CNumber&);
bool operator>(CNumber&);
bool operator==(CNumber&);
bool operator<=(CNumber&);
bool operator>=(CNumber&);

void operator+=(CNumber &t);
void operator-=(CNumber &t);
CNumber & operator++();
CNumber & operator++(int i);
/* CNumber & operator--(int i);*/
CNumber & operator--();


public:
friend CNumber &operator+(CNumber&,CNumber&);
friend CNumber &operator-(CNumber&,CNumber&);
friend CNumber &operator*(CNumber&,CNumber&);
friend CNumber &operator/(CNumber&,CNumber&);
public:
friend ostream & operator<<(ostream &,CNumber&);
/*
public:
void* operator new(std::size_t size) ;
void* operator new(std::size_t size, const std::nothrow_t&) ;
void operator delete(void* ptr) throw();
void operator delete(void* ptr, const std::nothrow_t&) ;
void* operator new[](std::size_t size) ;
void* operator new[](std::size_t size, const std::nothrow_t&) ;
void operator delete[](void* ptr) throw();
void operator delete[](void* ptr, const std::nothrow_t&) ;*/


public:
inline int CompareFountionEx(CNumber &t){//带符号比较
if(Symbols == t.Symbols){
int m_i = CompareFountion(HideNumber,t.HideNumber,Length,t.Length);
if(Symbols){
if(m_i!=2)
return m_i^1;
}
return m_i;
}
else{
if(Symbols)
return 0;
return 1;
}
}
inline int CompareFountion(BYTE *t1,BYTE *t2,UINT m_x){//不带符号比较
for(int i=m_x-1;i>=0;i--){
if(t1[i]>t2[i])
return 1;
else if(t1[i] == t2[i]){
if(i==0)
return 2;
continue;
}
else
return 0;
}
return -1;
}
inline int CompareFountion(BYTE *t1,BYTE *t2,UINT leng1,UINT leng2){//同长度比较
if(leng1>leng2)
return 1;
else if(leng1<leng2)
return 0;
else
return CompareFountion(t1,t2,leng1);
}
BYTE * DIVFountion(BYTE *,BYTE *,UINT,UINT,UINT &);
BYTE * AddFountion(BYTE *,BYTE *,UINT,UINT,UINT &);
BYTE * SubFountion(BYTE *,BYTE *,UINT,UINT,UINT &,UINT&,UINT m_z = -1);
BYTE * MulFountion(BYTE *,BYTE *,UINT,UINT,UINT &);
public:
inline BYTE * NumberBack(){
return Number;
}
inline UINT LengthBack(){
return Length;
}
inline BYTE * HideNumberBack(){
return HideNumber;
}
inline UINT SymbolsBack(){
return Symbols;
}

inline bool CopyHideNumber(BYTE *m_p=NULL,UINT m_x=0){//更新数据
if(m_p==NULL||m_x==0)
return 0;
MyNumber_delete();
Length = m_x;
Number = new BYTE[Length+1];
HideNumber = new BYTE[Length+1];
memcpy(HideNumber,m_p,Length+1);
for(UINT i=0;i<Length;i++)
Number[i] = HideNumber[--m_x]+48;
Number[Length] = '\0';
return 1;

}
inline void MyNumber_zero(){//清零
MyNumber_delete();
Symbols = 0;
Length = 1;
Number = new BYTE[2];
HideNumber = new BYTE[2];
memset(HideNumber,0,2);
memset(Number,0,2);
Number[0] = '0';
}
inline void MyNumber_one(){//清理数据 赋值1
MyNumber_delete();
Length = 1;
Number = new BYTE[2];
HideNumber = new BYTE[2];
memset(HideNumber,0,2);
memset(Number,0,2);
Number[0] = '1';
HideNumber[0] = 1;
}
protected:
inline bool MyNumber_delete(){
if(Length){
Length = 0;
delete [] HideNumber;
delete [] Number;
return 1;
}
else
return 0;
}
inline bool MyNumber_create(BYTE *p){
if(Length){
Number = new BYTE[Length+1];
HideNumber = new BYTE[Length+1];
memcpy(Number,p,Length+1);
UINT m_i = Length;
for(int i=0;i<Length;i++)
HideNumber[--m_i] = Number[i]-48;
HideNumber[Length] = '\0';
return 1;
}
return 0;
}
inline void ChangeOver(BYTE *p,UINT m_x){//倒转数据
UINT m_i = m_x/2;
BYTE m_c;
for(int i=0;i<m_i;i++){
m_c = p[i];
p[i] = p[--m_x];
p[m_x] = m_c;
}

}
inline void ChangeOverCopy(BYTE *p1,BYTE*p2,UINT m_x){//倒转复制
UINT m_i = m_x;
for(int i = 0;i<m_x;i++)
p1[i] = p2[--m_i];

}

virtual BYTE * CheckChar(char *m_p){//检查数据
while(m_p[0]!='\0'){
if(m_p[0]=='0'||(m_p[0]<='0'&&m_p[0]>'9')){
m_p++;
continue;
}
else
break;
}
if(m_p=='\0')
return NULL;
int m_i = strlen(m_p);
BYTE *m_p_one = new BYTE[m_i+1];
memset(m_p_one,0,m_i+1);
for(int i=0,j=0;i<m_i;i++){
if(m_p[i]>='0'&&m_p[i]<='9'){
m_p_one[j] = m_p[i];
j++;
}
}
return m_p_one;
}
/*
inline bool MyNumberCToB(){
for(UINT i=0;i<Length;i++)
}*/
public:
UINT Symbols;
protected:
UINT Length;

private:
BYTE *Number;
BYTE *HideNumber;

};
#endif
...全文
176 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
hahayezhe112 2010-08-24
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 ayw215 的回复:]
lz是为了练手么?
有一大堆开源的大数库实现,不必重复造轮子
[/Quote]
呵呵 嗯为了练手 别人的代码看得类 自己写的感觉更亲切
hahayezhe112 2010-08-24
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 renzhewh 的回复:]
More Effective C++ Item M20:协助完成返回值优化
[/Quote]

楼上的真不知道怎么感谢你好

谢谢了!
renzhewh 2010-08-24
  • 打赏
  • 举报
回复
More Effective C++ Item M20:协助完成返回值优化
renzhewh 2010-08-24
  • 打赏
  • 举报
回复

一个简单的复数类,lz看下,如何实现operator+与operator+=

#include <iostream>

// 简单的复数类,为了方便,接口与实现放在一起
class myComplex
{
public:
// constructor
myComplex(int real = 0, int image = 0)
: real_(real), image_(image)
{}


// operator
myComplex& operator+= (const myComplex& other)
{
real_ += other.real_;
image_ += other.image_;

return *this;
}

// print
friend std::ostream& operator<< (std::ostream& os, const myComplex& content)
{
return os << content.real_ << " " << content.image_;
}

private:
int real_;
int image_;
};

// 注意返回值类型,这里lhs、rhs都是const
myComplex operator+ (const myComplex& lhs, const myComplex& rhs)
{
return myComplex(lhs) += rhs;
}

int main()
{
myComplex a(10, 20);
myComplex b(20, 40);

myComplex c = a + b;
// 这里a、b的值都不会变
std::cout << "c = " << c << std::endl;
std::cout << "a = " << a << std::endl;
std::cout << "b = " << b << std::endl;

return 0;
}
ayw215 2010-08-24
  • 打赏
  • 举报
回复
lz是为了练手么?
有一大堆开源的大数库实现,不必重复造轮子
hao123CJ 2010-08-24
  • 打赏
  • 举报
回复
太长了点 没时间没兴趣看了
huayiluo 2010-08-24
  • 打赏
  • 举报
回复
楼主很虚心啊。比我厉害太多了。
大昊 2010-08-24
  • 打赏
  • 举报
回复
太长了
renzhewh 2010-08-24
  • 打赏
  • 举报
回复
lz 不是 return A + B
而是 return CNumber(A) += B;
是构建一个临时变量,使用A来初始化,在这个临时变量上执行赋值操作。不是改变A的值
你可以写个小程序检测一下
ropert911 2010-08-24
  • 打赏
  • 举报
回复
学习一哈
hahayezhe112 2010-08-23
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 renzhewh 的回复:]
真让人失望...
[/Quote]
不要失望罗
非常感谢你的回答
要不我现在在+=返回的都是void呢
hahayezhe112 2010-08-23
  • 打赏
  • 举报
回复
我现在最大的问题在于
怎么在友元中采用值传递的方式 返回函数中的临时对象
CNumber &operator+(CNumber&t1,CNumber&t2){
UINT m_i=0;
CNumber *m_cnumber=new CNumber;
m_cnumber->Symbols = t1.Symbols;
写成
CNumber operator+(CNumber&t1,CNumber&t2){
UINT m_i=0;
CNumber m_cnumber;
m_cnumber->Symbols = t1.Symbols;

返回一个局部对象的值。
因为用这种方法可以避免对于那个new出来的CNumber进行释放

我知道效率可能会底

如果不用值传递的话,还有什么其他好方法 采用auto_ptr智能指针进行转换么?能实现么

或者值采用指针接收? 返回一个对象的地址,然后再外面进行释放
不过这就不符合封装了,类也显得不完美

SuperLampard 2010-08-23
  • 打赏
  • 举报
回复
楼主 牛X 膜拜
hahayezhe112 2010-08-23
  • 打赏
  • 举报
回复
晕 讨论 讨论 别吵起来
发这帖子意在学习

楼上的 我用你说的测试过

比如 return A+=B; 它返回的值确实是 加过后的值,但是这里的A不再是原来的A了 而变成了A+B
也就是说
假如:A=1 ,B=2
return A+=B;返回的是3 但是A也变成3了,改变了A 这个感觉违背我的初衷,
我还想用这个大数类派生的实数类,派生出指数,对数等其他的类来呢!

真是非常感谢各位大佬的热衷回答
qq120848369 2010-08-23
  • 打赏
  • 举报
回复
语言与算法不分家,再学C++吧.
renzhewh 2010-08-23
  • 打赏
  • 举报
回复
真让人失望...
renzhewh 2010-08-23
  • 打赏
  • 举报
回复
回16#

"原本简单的A=B+C行为会被莫明奇妙的改成了A=B+C,B=B+C!" "会改变程序本身的逻辑行为"
不解,请问什么地方改变了B的值,楼上真的理解这行代码吗?

"对于对象进行过程化处理未尝不可,但对于数值操作来说,过程化就相当的恶心了"
何为过程化?

"建立中间变量缓冲池的方式"
如果编译器支持返回值优化的话,上述代码根本不存在临时变量,可以获得更佳的效率。

"限制在以行代码中出现过多的操作符"
这行代码仅含一个复制构造和一个复合赋值,如何会让人觉“过多”呢?
庄鱼 2010-08-23
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 renzhewh 的回复:]

C/C++ code

假设你定义了复合赋值
CNumber& operator+=(const CNumber& other);

下面这个函数这样调用它
CNumber operator+(const CNumber& lhs, const CNumber& rhs)
{
return CNumber(lhs) += rhs;
}
[/Quote]
这样的C++代码是极其恶心的,原本简单的A=B+C行为会被莫明奇妙的改成了A=B+C,B=B+C!这恰恰是将函数过程化的原因。C/C++本身是函数语言,对于对象进行过程化处理未尝不可,但对于数值操作来说,过程化就相当的恶心了,因为其会改变程序本身的逻辑行为,从而使程序真正变得不可知起来。我本人赞同建立中间变量缓冲池的方式,限制在以行代码中出现过多的操作符(譬如10个)这样,程序会变得更清晰而且符合使用上的数学习惯。
hahayezhe112 2010-08-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 renzhewh 的回复:]
C/C++ code

给些个人的看法:(错了,也请多指教:-))
首先是用法方面:
void operator+=(CNumber &t);
void operator-=(CNumber &t);
这类函数返回值应为 CNumber&
friend CNumber &operator+(CNumber&,CNumbe……
[/Quote]

我又理解了你的一些意思了
你的意思是 A= B+C 可以返回一个 B+=C

当是这样不就改变了B的值么
hahayezhe112 2010-08-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 renzhewh 的回复:]
C/C++ code

给些个人的看法:(错了,也请多指教:-))
首先是用法方面:
void operator+=(CNumber &t);
void operator-=(CNumber &t);
这类函数返回值应为 CNumber&
friend CNumber &operator+(CNumber&,CNumbe……
[/Quote]

谢谢 谢谢
不过+= 类的对象是作为左值的 所以不需要返回
+返回类的对象 而不动态new个出来 我一开始也是这么想的
但是无法返回一个内部临时的对象值,
所以我只能重新开一个
我的想法是重载new 或者改用C++智能指针,但在哪方面知识贫瘠 应用的少 正在努力学习中

加载更多回复(13)

64,647

社区成员

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

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