Mis*_*ded 3 c++ memory new-operator
我熟悉C++,而且我遇到了内存管理问题.在C中,每当我想为任意数量的元素保留内存时,无论何种类型,我都会调用malloc()然后手动初始化(通过循环),以我想要的任何值.使用C++ new,一切都是自动初始化的.
问题是,我有一个BattlePoint类,它有点像这样:
class BattlePoint {
public:
BattlePoint(int x, int y) : x(x), y(y) { };
bool operator==(const BattlePoint &right);
virtual ~BattlePoint();
private:
int x, y;
};
Run Code Online (Sandbox Code Playgroud)
如您所见,它通过初始化程序获取一些x和y值,然后从中设置自己的x和y.问题是,这个函数将从一个函数中调用,该函数将分配它们的数组:
BattleShip::BattleShip(BattlePoint start, enum shipTypeSize size, enum shipOrientation orientation) : size(size), orientation(orientation) {
points = new BattlePoint[size]; // Here be doubts.
}
Run Code Online (Sandbox Code Playgroud)
所以,我需要我的BattleShip的观点来保持一个BattlePoints数组,每个BattlePoints具有不同的初始值(例如0,1; 0,2; 0,3等).
问题是:我如何分配未初始化的内存?
朱利安
PS:我没有对工作方式做过任何测试new,我简单阅读维基百科关于它的文章说:
在C++编程语言中,以及在许多基于C++的语言中,new是一种语言结构,它在堆上动态分配内存并使用构造函数初始化内存.除了名为"placement new"的表单之外,新尝试在堆上为新数据分配足够的内存.如果成功,它会初始化内存并将地址返回给新分配和初始化的内存.但是,如果new无法在堆上分配内存,则会抛出std :: bad_alloc类型的异常.这消除了显式检查分配结果的需要.调用delete的调用必须在每次调用new时调用析构函数并将new分配的内存返回给堆,以避免内存泄漏.
placement new应该是解决方案,但它没有提到如何做到这一点.
PS 2:我知道这可以通过stdlib的vector类来完成,但是我故意避免使用它.
你需要使用一个std::vector.在这种情况下,你可以push_back随心所欲,例如
std::vector<BattlePoint> x;
x.push_back(BattlePoint(1, 2));
Run Code Online (Sandbox Code Playgroud)
如果你曾经发现自己使用new[],delete或者delete[],立即重构你的程序删除这样的.几乎在任何可想象的方式中,它们都是非常不安全的.相反,使用资源管理类,如std::unique_ptr,std::vector和std::shared_ptr.
经常new 可以在涉及某些情况下非常有用unique_ptr,但没有别的避免它.此外,新位置通常不值得.当然,如果你正在编写一个资源管理类,那么你可能不得不将它们用作底层基元,但这种情况很少而且很远.
编辑:我的错误,我没有看到你问题的最后一行.解决它:
PS 2:我知道这可以通过stdlib的vector类来完成,但是我故意避免使用它.
如果您有针对标准库的广告系列,请滚动您自己的vector替代品.但是不要没有vector上课.有一个原因必须由所有符合要求的编译器提供.
点数 = 新的战斗点 [大小]; // 这里有疑问。
PS 2:我知道这可以通过 stdlib 的向量类来完成,但我故意避免它。
肯定会有人质疑!使用std::vector. 你为什么不呢?有没有理由不使用std::vector,尤其是如果它解决您的问题。
std::vector<BattlePoint> bpoints;
bpoints.reserve(size); // there, only alloc'd memory, not initialized it.
bpoints.push_back(some_point); // still need to use push_back to initialize it
Run Code Online (Sandbox Code Playgroud)
我相信问题会来 - 如何std::vector只分配内存?!
operator new是答案。当您使用new. new用于构造和初始化,而operator new用于分配(这就是您可以重载它的原因)。
BattlePoint* bpoints = ::operator new(size); // happens in reserve
new (bpoints[index]) BattlePoint(some_x, some_y); // happens in push_back
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2828 次 |
| 最近记录: |