智能指针的一些问题?这个比较语句没有被执行的问题。

filia2014 2015-02-24 02:16:00
今天学到C++第三版的 智能指针 遇到的问题。


下面的结果和书上的不一样,书上是先输出的是第一个Box对象,然后使其自增加然后找寻最大的那个Box然后将其输出。


我的结果却一直是第一个Box对象。下面是输出结果。





发现中间一段根本没有做比较,但是程序还是运行了,

就是maxBox和*ploadbox之间的比较根本没有执行,程序还是输出的maxBox最初的那个地址。

是不是比较运算符的问题,比较的不是Box的类?但是*ploadbox的返回值是一个Box类的指针。

还是赋值运算符的问题。。。。。

main

#include <iostream.h>
#include <cstdlib>
#include <ctime>
using std::cout;
using std::endl;
#include "Box.h"
#include "List.h"
#include "BoxPtr.h"

inline int random(int count){
return 1+static_cast<int>
(count*static_cast<double>(std::rand())/(RAND_MAX+1.0));
}

int main(){
const int dimLimit=100;
std::srand((unsigned)std::time(0));

const int boxCount=20;
Box boxes[boxCount];

for(int i=0;i<boxCount;i++)
boxes[i]=Box(random(dimLimit),random(dimLimit),random(dimLimit));


TruckLoad load=TruckLoad(boxes,boxCount);

BoxPtr pLoadBox(load);

Box maxBox=*pLoadBox;
if(pLoadBox)
cout<<endl<<"Volume of first Box is "<<pLoadBox->volume();

while(++pLoadBox)
if(maxBox<*pLoadBox)
maxBox=*pLoadBox;



cout<<endl
<<"The largest box in the list is "
<<maxBox.getLength()<<" by "
<<maxBox.getWidth()<<" by "
<<maxBox.getHeight()<<" by "
<<maxBox.volume()<<endl;

return 0;

}


Box类的

class Box{
private:
double length;
double width;
double height;
static int objectCount;

public:
//Box();
Box(double aLength=1.0,double aWidth=1.0,double aHeight=1.0);
//~Box();
double volume ()const;

double getLength()const;
double getWidth()const;
double getHeight()const;

void pr();
bool operator<(const Box& aBox)const;
bool operator<(const double aValue)const;
Box operator+(const Box& aBox)const;
//Box operator=(Box& aBox);
int compareVolume (const Box & otherBox)const;
Box* setLength(double lvalue);
Box* setWidth(double wvalue);
Box* setHeight(double hvalue);
static double sam(Box theBox);
int getObjectCount()const;

};
inline bool Box::operator<(const Box& aBox)const{
return volume()<aBox.volume();
};
inline bool Box::operator<(const double aValue )const{
return volume()<aValue;
};

inline Box Box::operator+(const Box& aBox)const {
return Box(length>aBox.length?length:aBox.length,
width<aBox.width?width:aBox.width,
height+aBox.height);
};
//inline Box Box::operator=(Box& aBox){

// this->length=aBox.length;
//this->width=aBox.width;
//this->height=aBox.height;
//return *this;

//}

inline bool operator<(const double aValue,const Box& aBox){
return aValue<aBox.volume();
};


Box.cpp的

#include<iostream>
#include"Box.h"
using std::cout;
using std::endl;
//Box::Box(){
// cout<<"Default constructor called"<<endl;
// ++objectCount;
// length=width=height=1.0;}

Box::Box(double aLength,double aWidth, double aHeight){
double maxSide=aLength>aWidth?aLength:aWidth;
double minSide=aLength<aWidth?aLength:aWidth;
length=maxSide>0.0?maxSide:1.0;
width=minSide>0.0?minSide:1.0;
height=aHeight>0.0?aHeight:1.0;}

//Box::~Box(){
// cout<<"Box destructor called. "<<endl;
//}


double Box::volume()const{
return length*width*height;

}
double Box::getLength()const{
return length;
}
double Box::getWidth()const{
return width;
}
double Box::getHeight()const{
return height;
}
int Box::compareVolume(const Box& otherBox)const{
double vol1=volume();
double vol2=otherBox.volume();
return vol1>vol2?1:(vol1<vol2?-1:0);
}
Box* Box::setLength(double lvalue){
if(lvalue>0)length=lvalue;
return this;
}

Box* Box::setWidth(double wvalue){
if(wvalue>0)width=wvalue;
return this;
}

Box* Box::setHeight(double hvalue){
if(hvalue>0)height=hvalue;
return this;
}

void Box::pr(){
cout<<this->length<<" "<<this->width<<" "<<this->height<<" "<<endl;
}
int Box::getObjectCount()const{
return objectCount;
}
double Box::sam(Box theBox){
return theBox.length+theBox.width+theBox.height;
}

int Box::objectCount=0;


BoxPtr.h的

class BoxPtr{
public:
BoxPtr(TruckLoad& load);
Box& operator*()const;
Box* operator->()const;
Box* operator++();
const Box* operator++(int);
operator bool();

private:
Box*pBox;
TruckLoad& rLoad;

BoxPtr();
BoxPtr(BoxPtr&);
BoxPtr& operator=(const BoxPtr&);
};


BoxPtr.cpp的

using std::cout;
using std::endl;

BoxPtr::BoxPtr(TruckLoad& load):rLoad(load){
pBox=rLoad.getFirstBox();
}

Box& BoxPtr::operator*()const{
if(pBox)
return *pBox;
else{
cout<<endl<<"Dereferencing null BoxPtr";
return *pBox;
}
}

Box* BoxPtr::operator->()const{
return pBox;
}

Box* BoxPtr::operator++(){
return pBox=rLoad.getNextBox();
}

const Box* BoxPtr::operator++(int){
Box* pTemp=pBox;
pBox=rLoad.getNextBox();
return pTemp;
}

BoxPtr::operator bool(){
return pBox!=0;
}



TuckLoad.h的

class TruckLoad{
public:
TruckLoad(Box* pBox=0,int count=1);
~TruckLoad();
TruckLoad(const TruckLoad& load);
TruckLoad&operator=(const TruckLoad& load);
Box operator[](int index)const;
Box* getFirstBox();
Box* getNextBox();
void addBox(Box* pBox);

private:
class Package{
public:
Package(Box* pNewBox);
~Package();
Package(Box& pNewBox);
void setNext(Package* pPackage);

Box* pBox;//一个包含Box类型的引用
Package* pNext;//一个Paclage类型的指针变量
};
Package* pHead;
Package* pTail;
Package* pCurrent;};

TtuckLoad.cpp的


using std::cout;
using std::endl;
TruckLoad::Package::Package(Box* pNewBox):pBox(pNewBox),pNext(0){}//package对象有两个数据
//一个是box类型的指针pBox,一个是指向下一个box类型的package类型指针pNext。

TruckLoad::Package::~Package(){
cout<<"Package destructor called. "<<endl;
}

void TruckLoad::Package::setNext(Package* pPackage){pNext=pPackage;}//该函数接受package类型的指针参数
//将他赋值给pNext数据 (存储私有数据)


TruckLoad::TruckLoad(Box* pBox,int count){
pHead=pTail=pCurrent=0;//如果不带参数的默认构造函数,三个指针数据都为空

if((count>0)&&(pBox!=0))//带参数且count大于0,构建count个box对象
for(int i=0;i<count;i++)
addBox(pBox+i);
return;
}//(建立链表对象)

TruckLoad::~TruckLoad(){
cout<<"TruckLoad destructor called. "<<endl;
while(pCurrent=pHead->pNext){
delete pHead;
pHead=pCurrent;
}
delete pHead;
};
TruckLoad::TruckLoad(const TruckLoad& load){
pHead=pTail=pCurrent=0;
if(load.pHead==0)
return;

Package* pTemp=load.pHead;
do{
addBox(pTemp->pBox);
}while(pTemp=pTemp->pNext);

}

void TruckLoad::addBox(Box* pBox){
Package* pPackage=new Package(pBox);//将参数pBox传来的地址传给一个新的Package
//类型的对象,并赋值给一个pPackage临时指针。

if(pHead)//如果该函数的Truckload对象的head指针存在
pTail->pNext==pPackage;//将新对象的首地址作为参数,传送给当前Tail指针指向的对象的pNext数据
else
pHead=pPackage;//将head指针指向新对象的首地址
pTail=pPackage;//将Tail指针指向新对象的首地址
}//(建立package对象并将他们相连 )

Box* TruckLoad::getFirstBox(){
pCurrent=pHead;//将Head指针的地址传给Current指针
return pCurrent->pBox;//返还Current指针指向对象的pBox指针
}//(获取第一个Box对象的地址)

Box* TruckLoad::getNextBox(){
if(pCurrent)//如果Current指针存在
pCurrent=pCurrent->pNext;//将当前Current指针指向的对象的pNext指针地址传给Current指针。
else
pCurrent=pHead;//将Head指针地址传给Current指针

return pCurrent?pCurrent->pBox:0;//如果Current指针存在,返还它当前所指向对象的pBox地址,否则返还0
}//(访问下一个Box对象的地址)
Box TruckLoad::operator[](int index)const{
if(index<0){
cout<<endl<<"Negative index";
return *pTail->pBox;
}

Package*pPackage=pHead;
int count=0;
do{
if(index==count++)
return *pPackage->pBox;
}while(pPackage=pPackage->pNext);
cout<<endl<<"Out of range index ";
return *pTail->pBox;
}
TruckLoad& TruckLoad::operator=(const TruckLoad& load){
if(this==&load)
return*this;

while(pCurrent=pHead){
pHead=pHead->pNext;
delete pCurrent;
}

pHead=pTail=pCurrent=0;
if(load.pHead==0)
return*this;

Package* pTemp=load.pHead;
do{
addBox(pTemp->pBox);
}while(pTemp=pTemp->pNext);
return*this;
}
...全文
173 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
forget0915 2015-02-27
  • 打赏
  • 举报
回复
用boost库的share_ptr替代std库的智能指针
赵4老师 2015-02-25
  • 打赏
  • 举报
回复
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒:再牛×的老师也无法代替学生自己领悟和上厕所! 单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
filia2014 2015-02-24
  • 打赏
  • 举报
回复
不是,随机数没问题,调用的是系统时间,我模拟输出20个BOX对象没问题,每次随即的也不一样。

主要是first和larger的每次都一样,中间那个循环比较没有执行,把结构换成for循环,对象都调用BOX对象比较,也没问题,就是不知道这两个运算符问题出在哪里,都是按照书上写的。
ysnis 2015-02-24
  • 打赏
  • 举报
回复
没有设置随机数种子,每次随机数种子都自动设成相同值1 ,进而导致rand()所产生的随机数值都一样 inline int random(int count){ return 1+static_cast<int> (count*static_cast<double>(std::rand())/(RAND_MAX+1.0)); } int main(){ const int dimLimit=100; std::srand((unsigned)std::time(0)); ----------- 放进前面的random函数里

65,210

社区成员

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

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