use*_*473 0 c++ memory-management
我发现自己经常不假思索地编写类,这些类添加指向对象的指针,这些对象后来被销毁到列表中,这导致了很多段错误,但问题是有时我根本无法提出比存储列表更好的解决方案指针.我认为,在C++中似乎没有一种简单的方法可以"存储你无法复制的临时对象".有没有关于如何有效地做到这一点的范例?
例如,我将有一个看起来像这样的类:
class MyClass
public:
std::vector<OtherClass *> other_objects;
void method() {
OtherObject other_object = create_other_object();
other_objects.push_back(&other_object);
}
Run Code Online (Sandbox Code Playgroud)
您可能想要这样做的一个原因是因为您使用other_objects其他地方(作为其他函数的参数)并且您无法复制OtherObject实例(例如,如果OtherObject复制构造函数是私有的,则可能会发生这种情况).
当然,一旦你尝试other_objects在代码中的其他地方使用,每个指针指向的内存将被破坏.
我写了很多的Python代码,我用这种结构非常频繁,其中一个方法填充的迭代与该方法的范围内单独存在的对象.有没有办法在C++中有效地做到这一点?我可以自己进行内存管理,以使方法中的临时对象保持活动超出方法范围吗?
在C++中创建指针列表的正确范例是什么?
将std::list(或者某些其他容器)与一些智能指针类(参见此处)(例如std::shared_ptr或)组合在一起std::unique_ptr.
根据经验(有时是错误的)避免使用原始指针并且更喜欢智能指针.内存管理是一个棘手的话题.如果您阅读了一些关于垃圾收集的书(例如GC手册),您将学习相关的概念,术语和技术(这些甚至适用于手动内存管理,例如引用计数 - 有些人认为这是GC的原始形式) .循环引用很难处理(请注意弱引用,例如std::weak_ptr).
这里需要花费大量的时间和空间来详细解释所有这些(而且我没有时间或动力,甚至没有所有技能).阅读一本好的C++编程书并参考一些C++参考(后来可能是C++ 11标准n3337或更新版本).请注意,C++ 的内存模型很难理解(对任何人而言).
要注意五个规则.
在某些操作系统和/或C++实现,你可以找到的工具,比如Valgrind的或地址消毒剂的铛或GCC,这将有助于您调试,然后避免内存泄漏(细节编译器和/或OS特定).在少数 情况下(可能是其中的一小部分),您可以考虑使用垃圾收集器库(例如Boehm的GC,请参阅此内容或MPS).
有没有办法在C++中有效地做到这一点?
我不知道有任何有效,通用和简单的方法(赖斯的定理让我相信没有一个)来管理记忆.你的里程会有所不同.您需要准确理解您的内存管理和其他编程约束和目标,并进行自己的权衡.见Norvig的观点.有没有银弹.
PS.C++是一种非常困难的编程语言.准备好自己花费大量时间(几年,而不是几个月;也许几十年)并努力学习它.另外,从灵感来看,也可以看一些用C++ 编写的编写良好的免费软件的源代码.我并不认为自己是C++大师(即使我的日常工作是为它设计和实现一些静态源代码分析器).我相信这个星球上可能只有几十个(或者几百个)C++大师,我不在其中.
PPS.我有偏见,但我建议在你的开发机器上使用 Linux来学习C++编程,正是因为它有很多有用的工具.
不,你没有理由这样做:
OtherObject other_object = create_other_object();
other_objects.push_back(&other_object);
Run Code Online (Sandbox Code Playgroud)
这将创建一个临时对象,并将指针存储在列表中,然后销毁该对象.
这是与Python的主要区别.在Python中,每个对象都是对Python对象的引用,甚至是整数.在C++中,你有堆栈(像你这样),或在堆上(通过创建对象上new,make_unique...).如果要模仿Python行为,则需要堆上的对象.
只有三种有效模式,具体取决于create_object():
make_unique以获得副本.这种模式通常不是很有用而且不实用.std::unique_ptr<OtherClass> create_other_object();OtherClass* create_other_object();在你的情况下,它可能是第二种情况:
std::vector<std::unique_ptr<OtherClass>> other_objects;
void method() {
other_objects.push_back(create_other_object());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
91 次 |
| 最近记录: |