容器中存储对象还是指针

lwmonster 2014-05-21 10:00:41
大神教导我们,容器中要存对象,不要存指针,但是我遇到了下面的问题:
下面代码,我在容器中存对象的时候, 子类的虚函数是不能被执行的,只有存指针才能被执行, 是不是我的使用方式有问题?


class A {
public:
virtual void fun(){
cout << "in A" << endl;
}
};
class B : public A {
public:
string name;
};
class C : public B {
public :
virtual void fun(){
cout << "in C" << endl;
}
};
int main(){
vector<A> vec;
vec.push_back(C());
vec[0].fun();
/** 这段代码才有用
vector<A*> vec;
vec.push_back(new C());
vec[0]->fun();
**/
}


...全文
843 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2015-10-10
  • 打赏
  • 举报
回复
2)动态分配的指针,不做任何修改指针的操作,或者修改前释放掉内存。 同时,不修改容器的容量,和指针的值(在容器内部交换指针元素是可以的,不能做别的处理了) 也就是保证容器内的每个指针都没有丢失,老老实实在容器内呆着, 需要单独修改变动的时候, 要先释放旧有的内存,不能二话不说,就擦除了,改为NULL了,赋予一个新值了, 容器很多方法,算法,有这个潜在特性。 这种算法就不能用了。
lm_whales 2015-10-10
  • 打赏
  • 举报
回复
不是不能存,而是不方便, 容器不是设计为处理指针的, 而是设计为处理对象的, 所以和指针有些冲突。 容易出问题的地方举例: 因为 1)指针和对象的生存期可能是不同的, 如果容器中元素是指向局部对象的指针, 传出函数后,指针就无效了,所指对象超过生存期了。 2)对于对象 push_back这一类函数, 复制对象的值,没问题,假设对象的值改变了, push_back进去是一个新对象 和 参数变量名,无关,也没问题。 如果用指针,指向同一个的对象, 这个对象每次改变为不同值,但是 push_back 复制的指针是同一个指针值, 那么,历史上push_back 的所有指针的值都相同, 对象变量的历史上拥有的值,没有记录下来。 3)容器有很多相关的算法函数,会改变容器中的元素和容器的大小,而push_back 的指针,如果是动态分配的 这种时候,就没有机会释放内存了,造成内存泄露 而对象就没有这个问题,该构造的构造,该析构的析构,没有任何问题 容器中,可以使用指针的场合举例: 1)容器只在函数内部使用,或者容器内部的元素,就是指向全局对象指针. 2)动态分配的指针,不做任何修改指针的操作,或者修改前释放掉内存。 3)动态分配的指针,存在在一个不会修改的容器中,作为备份,其拷贝存入其他容器, 一且操作都不以释放内存为条件。 不再使用的时候,释放内存。
bear234 2015-10-09
  • 打赏
  • 举报
回复
"大神教导我们,容器中要存对象,不要存指针" 大神请现身,求教育,为什么???
FrankHB1989 2014-06-07
  • 打赏
  • 举报
回复
引用 34 楼 daiweifeng 的回复:
[quote=引用 28 楼 FrankHB1989 的回复:] [quote=引用 16 楼 daiweifeng 的回复:] [quote=引用 13 楼 FrankHB1989 的回复:] 哪个神棍告诉你的。 该用啥用啥。
容器里直接使用指针是非常不好的习惯,可以利用C++模板和封装技术将基指针封装一下,并且在封装类中解决内存释放行为,比如各种智能指针。[/quote] 释放?你怎么就知道一定需要所有权? 虽然内建指针类型是逗比,但对于能看见实现的场合还真犯不着非得包一层告诉这里是“没有所有权也不想做指针算术的可变可空引用”,太麻烦。倒是保证非空指针又不想成员引用干扰特殊成员函数的默认定义,尽量用std::reference_wrapper强调nullable还有些可用性(虽然罗嗦了点但好歹是现成的)。 [/quote] 你可以在智能指针模板类里扩展相应的trait。当然了,如果你自个儿写的局部代码别人不用的那可能塞个指针暂时问题不大。 [/quote] 不是所有智能指针都提供trait让你扩展。标准库的就没有。把unique_ptr的deleter写成no-op之类基本也是多此一举。
超级能量泡泡 2014-06-06
  • 打赏
  • 举报
回复
引用 28 楼 FrankHB1989 的回复:
[quote=引用 16 楼 daiweifeng 的回复:] [quote=引用 13 楼 FrankHB1989 的回复:] 哪个神棍告诉你的。 该用啥用啥。
容器里直接使用指针是非常不好的习惯,可以利用C++模板和封装技术将基指针封装一下,并且在封装类中解决内存释放行为,比如各种智能指针。[/quote] 释放?你怎么就知道一定需要所有权? 虽然内建指针类型是逗比,但对于能看见实现的场合还真犯不着非得包一层告诉这里是“没有所有权也不想做指针算术的可变可空引用”,太麻烦。倒是保证非空指针又不想成员引用干扰特殊成员函数的默认定义,尽量用std::reference_wrapper强调nullable还有些可用性(虽然罗嗦了点但好歹是现成的)。 [/quote] 你可以在智能指针模板类里扩展相应的trait。当然了,如果你自个儿写的局部代码别人不用的那可能塞个指针暂时问题不大。
rmaly 2014-06-04
  • 打赏
  • 举报
回复
多态必须得指针调用或引用调用
FrankHB1989 2014-06-03
  • 打赏
  • 举报
回复
引用 24 楼 sniffer12345 的回复:
[quote=引用 14 楼 FrankHB1989 的回复:] [quote=引用 12 楼 sniffer12345 的回复:] 全上指针吧 万一不小心return一个vector,好歹还能跑跑。要是实例的话,呵呵。
瞎折腾。 一不小心没搞好rules of three生存期没控制好就直接挂了。[/quote] 汗 太较真了你[/quote] 这不是较真不较真的问题,实际上早年搜索到一些提问里经常能看到这类bug,特别是一些习惯C的用户……(虽然有多少进入生产环境是没法统计了)。近几年大概教育跟上了,这样低级的问题稍微不多见了。
FrankHB1989 2014-06-03
  • 打赏
  • 举报
回复
引用 28 楼 FrankHB1989 的回复:
[quote=引用 16 楼 daiweifeng 的回复:] [quote=引用 13 楼 FrankHB1989 的回复:] 哪个神棍告诉你的。 该用啥用啥。
容器里直接使用指针是非常不好的习惯,可以利用C++模板和封装技术将基指针封装一下,并且在封装类中解决内存释放行为,比如各种智能指针。[/quote] 释放?你怎么就知道一定需要所有权? 虽然内建指针类型是逗比,但对于能看见实现的场合还真犯不着非得包一层告诉这里是“没有所有权也不想做指针算术的可变可空引用”,太麻烦。倒是保证非空指针又不想成员引用干扰特殊成员函数的默认定义,尽量用std::reference_wrapper强调nullable还有些可用性(虽然罗嗦了点但好歹是现成的)。 [/quote] 强调nullable→强调非nullable。
FrankHB1989 2014-06-03
  • 打赏
  • 举报
回复
引用 16 楼 daiweifeng 的回复:
[quote=引用 13 楼 FrankHB1989 的回复:] 哪个神棍告诉你的。 该用啥用啥。
容器里直接使用指针是非常不好的习惯,可以利用C++模板和封装技术将基指针封装一下,并且在封装类中解决内存释放行为,比如各种智能指针。[/quote] 释放?你怎么就知道一定需要所有权? 虽然内建指针类型是逗比,但对于能看见实现的场合还真犯不着非得包一层告诉这里是“没有所有权也不想做指针算术的可变可空引用”,太麻烦。倒是保证非空指针又不想成员引用干扰特殊成员函数的默认定义,尽量用std::reference_wrapper强调nullable还有些可用性(虽然罗嗦了点但好歹是现成的)。
赵4老师 2014-06-03
  • 打赏
  • 举报
回复
容器中存储整个互联网内容还是到google的链接?
幻夢之葉 2014-06-03
  • 打赏
  • 举报
回复
只有用指针才能在运行时动态调用,你对象的话编译的时候是绑定调用哪个函数了的! 所以你用第二个方法来存储吧 记得delete!
qq120848369 2014-05-24
  • 打赏
  • 举报
回复
C对象仅仅是拷贝给了A对象,对象本身没有多态行为,这个是基础常识,如果你知道A的构造函数是这样实现的你不会感到奇怪: A(const A&); 因为C继承自A,A&自然会取出C中A的部分,完成拷贝。
对象 2014-05-24
  • 打赏
  • 举报
回复
你这里只是发生了个数据拷贝,没有任何多态出现。 你在给vector[0]赋值的时候,因为是A类型,不是C类型,而A是C的父类,所以C的对象发生了一个数据截断,只保留了A的部分。 而且,谁说过容易不能存指针?真是笑话。
idzeta 2014-05-24
  • 打赏
  • 举报
回复
引用 4 楼 baichi4141 的回复:
不知道是谁告诉你容器中要存对象不要存指针,但容器和多态的确是不相容的 如果要用继承,就必须用指针或引用,如果还要用容器,那就只能用指针
其实还可以用侵入式容器。
lm_whales 2014-05-23
  • 打赏
  • 举报
回复
可以存储智能指针
Arnis1973 2014-05-23
  • 打赏
  • 举报
回复
存贮的是指针
lming_08 2014-05-23
  • 打赏
  • 举报
回复
引用 17 楼 lming_08 的回复:
参考陈浩写的一篇博客
C++的数组不支持多态
http://coolshell.cn/articles/9543.html
汗,题目没看清,你这个多态必须得要指针才能实现啊
版主大哥 2014-05-23
  • 打赏
  • 举报
回复
int main(){ vector<A> vec; vec.push_back(C()); //这里C()生成一个C的对象,但是vector是接收A类型的,所以进行强制转换,刚好C是A的派生类,导致内存切割了,C对象转换的时候数据丢失(是对象,不是指针) vec[0].fun();
小辉辉 2014-05-23
  • 打赏
  • 举报
回复
当vector中参数是A*时,应该把指针作为参数传入,你传的是实例。只有指针才有动态绑定。
小辉辉 2014-05-23
  • 打赏
  • 举报
回复
#include "stdafx.h" #include "iostream" #include "vector" using namespace std; class A { public: virtual void fun(){ cout << "in A" << endl; } }; class B : public A { public: string name; }; class C : public B { public : virtual void fun(){ cout << "in C" << endl; } }; int main(){ vector<A> vec; vec.push_back(C()); vec[0].fun(); vector<A*> sec; sec.push_back(&C()); sec[0]->fun(); }
加载更多回复(18)

64,282

社区成员

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

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