c++继承中有关shared_ptr的一些疑问

sinat_27233737 2017-05-08 04:19:17

class Basket {
public:
void add_item(const std::shared_ptr<Quote>& q) {
item.insert(q);
}
double print_price(std::ostream& os) const{
double sum=0;
for (auto i = item.cbegin(); i != item.cend(); i = item.upper_bound(*i)) {
sum += print_total(os, **i, item.count(*i));
}
os << "书的总价格为:" << sum << std::endl;
return sum;
}
private:
static bool compare(const std::shared_ptr<Quote> &p, const std::shared_ptr<Quote> &q) {
return p->bookNo < q->bookNo;
}
std::multiset<std::shared_ptr<Quote>,decltype(compare)*> item{compare};//2、这里也不太懂
};


其中,BulkQuote是Quote的派生类,代表有打折的书。

int main() {
Basket basket;
BulkQuote a("a", 10, 5, 0.5);
basket.add_item(make_shared<BulkQuote>(a));//1、这里不懂!
basket.print_price(cout);


1、这里为什么写成“ basket.add_item(make_shared<BulkQuote>(a));”就不行,调用的是静态类型,即Quote,得到的是没打折时的价格?非要写成basket.add_item(make_shared<BulkQuote>(“a”,10,5,0.5));才可以呢?
还有,为什么不可以写成"basket.add_item(new BulkQuote(a));"提示"不存在从'BulkQuote*'到std::shared_ptr<Quote>"的适当构造函数?

2、 item{compare}这里为什么要定义成花括号,之前这里不都是定义成圆括号的吗?还有compare函数需要定义成static的呢?
...全文
788 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
开心秋水 2017-07-01
  • 打赏
  • 举报
回复
第一个问题, 你的代码不全, 一些函数我们也不知道你是怎么定义的, 所以不好说, 至于 "为什么不可以写成"basket.add_item(new BulkQuote(a));"提示"不存在从'BulkQuote*'到std::shared_ptr<Quote>"的适当构造函数?" 因为add_item函数的参数类型是shared_ptr<Quote>, 而BulkQuote*指针不能直接隐式的转换成这个类型, 不过它可以经过两次隐式转换得到: BulkQuote* --> Quote* --> shared_ptr<Quote>, 但参数的转换是不能经过两次隐式转换的.
sdghchj 2017-07-01
  • 打赏
  • 举报
回复
make_shared<BulkQuote>(a)调用的就是BulkQuote的拷贝构造函数, 不行就看它的拷贝构造函数是不是被delete了啊。 BulkQuote*不有转换到std::shared_ptr<Quote>不是楼上说的什么不能两次转换的原因(人家shared_ptr类本就提供了不同模板类指针间的reset函数),原因是 template<class _Ux> explicit shared_ptr(_Ux *_Px) { // construct shared_ptr object that owns _Px _Resetp(_Px); } explicit表明裸指针不能隐式转换为shared_ptr. C++11的STL容器都已经支持初始化列表std::initialize_list了,大括号就是初始化列表。 回调函数不一定非要是静态成员函数,还可以是全局函数,lambda函数,函数对象,std::function模板类绑定的各种函数包括成员函数。你要是熟了想怎么写就怎么写。
开心秋水 2017-06-30
  • 打赏
  • 举报
回复
第二个问题: 大括号初始化, 这是C++11的新特性:list initialization http://en.cppreference.com/w/cpp/language/list_initialization compare当然需要定义成static , 因为如果不是static, 则第一个(隐含的)参数是this指针, 而multiset这个构造函数接受的参数是一个比较参数的函数, 这个比较函数是只有两个参数的, 第一次参数不是这个this指针的类的类型. 所以, 需要是类的静态函数, 或者全局函数.
qq229873466 2017-06-30
  • 打赏
  • 举报
回复
好复杂,没看懂
C++智能指针详解 智能指针详解 智能指针内容很多,重点是基本⽤法。 #include shared_ptr.hpp> class CBase: public boost::enable_shared_from_this { public: virtual void f(){}//必须有个虚函数才能向上向下转换。 } typedef boost::shared_ptr CBasePtr; class CChild: public CBase {} typedef boost::shared_ptr CChildPtr; void main() { CBasePtr ptrBase = boost::make_shared(); //CBasePtr ptrBase = CBasePtr(new CBase()); // 向下转换 CChildPtr ptrChild = boost::dynamic_pointer_cast(ptrBase); // 向上转换 CBasePtr ptrXXX = ptrChild; // 普通转换 CChildPtr ptrXX = CChildPtr(dynamic_cast(ptrXXX.get())); } 暂时学会这些⽤法即可。 url: C++ 智能指针详解 ⼀、简介 由于 C++ 语⾔没有⾃动内存回收机制,程序员每次 new 出来的内存都要⼿动 delete。程序员忘记 delete,流程太复杂,最终导致没 有 delete,异常导致程序过早退出,没有执⾏ delete 的情况并不罕见。 ⽤智能指针便可以有效缓解这类问题,本⽂主要讲解参见的智能指针的⽤法。包 括:std::auto_ptrboost::scoped_ptr、boost::shared_ptr、boost::scoped_array、、boost::weak_ptr、boost::intrusive_ptr。你可能会想,如 此多的智能指针就为了解决new、delete匹配问题,真的有必要吗?看完这篇⽂章后,我想你⼼⾥⾃然会有答案。 下⾯就按照顺序讲解如上 7 种智能指针(smart_ptr)。 ⼆、具体使⽤ 1、总括 对于编译器来说,智能指针实际上是⼀个栈对象,并⾮指针类型,在栈对象⽣命期即将结束时,智能指针通过析构函数释放有它管理的 堆内存。所有智能指针都重载了"operator->"操作符,直接返回对象的引⽤,⽤以操作对象。访问智能指针原来的⽅法则使⽤"."操作符。 访问智能指针包含的裸指针则可以⽤ get() 函数。由于智能指针是⼀个对象,所以if (my_smart_object)永远为真,要判断智能指针的裸指 针是否为空,需要这样判断:if (my_smart_object.get())。 智能指针包含了 reset() ⽅法,如果不传递参数(或者传递 NULL),则智能指针会释放当前管理的内存。如果传递⼀个对象,则智能指 针会释放当前对象,来管理新传⼊的对象。 我们编写⼀个测试类来辅助分析: class Simple { public: Simple(int param = 0) { number = param; std::cout << "Simple: " << number << std::endl; } ~Simple() { std::cout << "~Simple: " << number << std::endl; } void PrintSomething() { std::cout << "PrintSomething: " << info_extend.c_str() << std::endl; } std::string info_extend; int number; }; 2、std::auto_ptr std::auto_ptr 属于 STL,当然在 namespace std ,包含头⽂件 #include 便可以使⽤。std::auto_ptr 能够⽅便的管理单个堆 内存对象。 我们从代码开始分析: void TestAutoPtr() { std::auto_ptr my_memory(new Simple(1)); // 创建对象,输出:Simple:1 if (my_memory.get()) { // 判断智能指针是否为空 my_memory->PrintSomething(); // 使⽤ operator-> 调⽤智能指针对象的函数 my_memory.get()->info_extend = "Addition";

33,321

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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