编写C++ Primer书上的 一个句柄类的例子运行时出错,请各位好心的大侠帮帮忙

dj_highman 乐视云 安全工程师  2012-11-28 05:14:44
程序代码如下:
定义一个包含类定义的头文件head1
#ifndef HEAD1_H
#define HEAD1_H
#include <iostream>

//不适用折扣策略的基类
class Item_base
{
public:
Item_base(const std::string &book="",double sales_price=0.0):isbn(book),price(sales_price){}
std::string book() const
{
return isbn;
}
virtual double net_price(size_t n) const
{
return n*price;
}
virtual ~Item_base()
{
std::cout<<"Destroy!"<<std::endl;
}

virtual Item_base* clone() const
{
return new Item_base(*this);
}

private:
std::string isbn;
protected:
double price;
};

class Disc_item:public Item_base
{
public:
Disc_item(const std::string &book="",double sales_price=0.0,size_t qty=0,double disc_rate=0.0):Item_base(book,sales_price),quantity(qty),discount(disc_rate){}

double net_price(size_t ) const=0;
std::pair<size_t,double>discount_policy() const
{
return std::make_pair(quantity,discount);
}
protected:
size_t quantity;
double discount;
};

//批量折扣购买类
class Bulk_item:public Disc_item
{
public:
Bulk_item(const std::string &book="",double sales_price=0.0,size_t qty=0,double disc_rate=0.0):Disc_item(book,sales_price,qty,disc_rate){}
double net_price(size_t cnt) const
{
if (cnt>=quantity)
{
return cnt*(1-discount)*price;
}
else
return cnt*price;
}



};

//有限折扣类
class Lds_item:public Disc_item
{
public:
Lds_item(const std::string &book="",double sales_price=0.0,
size_t qty=0,double disc_rate=0.0):Disc_item(book,sales_price,qty,disc_rate){}
double net_price(size_t cnt) const
{
if (cnt<=quantity)
{
return cnt*(1-discount)*price;
}
else
return cnt*price-quantity*discount*price;
}


};

class Sales_item //创建的句柄类
{
public:
Sales_item():p(0),use(new size_t(1)){}
Sales_item(Item_base& it):p(&it),use(new size_t(1)){}
Sales_item(const Sales_item& i):p(i.p),use(i.use)
{
++*use;
}
~Sales_item()
{
decr_use();
}
Sales_item& operator=(Sales_item& rhs)
{
++rhs.use;
decr_use();
p=rhs.p;
use=rhs.use;
return *this;
}
const Item_base* operator->() const
{
if (p)
{
return p;
}
else
throw std::logic_error("unbound Sales_item");
}
const Item_base& operator*() const
{
if (p)
{
return *p;
}
else
throw std::logic_error("unbound Sales_item");

}

private:
Item_base *p;
size_t *use;
void decr_use()
{
if (--*use==0)
{
delete use;
delete p; //貌似此处有问题

}

}
};

#endif

主函数main如下
int main()
{

Item_base Item("I am Sam",70.0);
Bulk_item Bulk("I am Sam",70.0,5,0.1);
Sales_item Sales_I(Item);
cout<<Sales_I->net_price(10)<<endl;
Sales_item Sales_B(Bulk);
cout<<Sales_B->net_price(10)<<endl;
return 0;

}

编译通过,但是运行的时候提示错误,感觉好像是指针哪里有问题,调试的时候在delete p处出错,去掉这句话就运行正常,小弟新手,请高手帮忙
...全文
123 点赞 收藏 6
写回复
6 条回复
dj_highman 2012年11月29日
我好像发现问题了,麻烦谁能解释一下以下代码为什么运行出错 class A { public: int m_a; }; class B : public A { public: int m_b; }; int main() { B b; A* ptr=&b; // A* ptr=new B(); delete ptr; return 0; } 而把A* ptr=&b替换成A* ptr=new B()就运行正确
回复 点赞
从此无她不见月 2012年11月29日
貌似不行。
回复 点赞
从此无她不见月 2012年11月29日

  private:
  Item_base *p;
  size_t *use;
把此段代码移到

class Sales_item   //创建的句柄类
{
  private:
  Item_base *p;
  size_t *use;
然后再运行。
回复 点赞
dj_highman 2012年11月29日
不好意思,代码有些乱哈,是C++ Primer书上的一道习题。我创建了一个句柄类——Sales_item,包含一个指向基类的指针和一个记数指针,主函数中通过Sales_item动态绑定到基类Item_base或者派生类Bulk_item。 至于类Lds_item,Disc_item在主函数中没用,可以基本不看。只是在主函数return返回是调用句柄类的析构函数时好像有问题,体现就是运行时报错。我把句柄类中的delete p这句话(用绿色标注)去掉后就没有错误了,我不清楚是为什么
回复 点赞
秋风细雨 2012年11月29日
首先一点:C++里面new 和delete成对使用是最佳也是最好的编程习惯 这里A* ptr=&b;这行是将b的地址复制给ptr, 也就是ptr指向了b, 然后你delete ptr时会释放b占用的内存, 而main()函数结束时会调用b的析构函数,再次delete b,因此会出错。。。
回复 点赞
wintree 2012年11月28日
代码不规范,没人愿意看啊!!
回复 点赞
发动态
发帖子
C++ 语言
创建于2007-09-28

3.1w+

社区成员

24.8w+

社区内容

C++ 语言相关问题讨论,技术干货分享
社区公告
暂无公告