到目前为止,我一直在用Java编写程序.所以当我开始使用C++时,首先想到的是如何破坏/删除/完成我不再需要的对象.
使用Java我曾经将它们设置null为垃圾收集器正在处理它.但是,我不知道C++的价值.我发现这篇文章http://en.wikipedia.org/wiki/Comparison_of_Java_and_C%2B%2B解决了我的大部分问题.但仍有一些我不明白的事情.
1)在Java中有一种方法可以强制垃圾收集器在现场清理(这并不总是有用,因为它在运行之前等待一些垃圾堆叠).有没有办法用C++做到这一点?
2)(C++)与上面相反,我怎样才能使对象处于"标记为删除"的状态,程序决定何时清理它(如Java)?
3)(C++)我应该强迫垃圾收集器在现场清理(我很确定这不是正确的方式,但我要求确定)?
如果你能给出一个代码触发器的小代码示例,我会赞美它.
如果结构被完全复制,那么第一个循环比第二个循环更昂贵,因为它正在为v的每个元素执行额外的副本.
vector<MyStruct> v;
for (int i = 0; i < v.size(); ++i) {
MyStruct s = v[i];
doSomething(s);
}
for (int i = 0; i < v.size(); ++i) {
doSomething(v[i]);
}
Run Code Online (Sandbox Code Playgroud)
假设我想编写有效的代码(如在循环2中),但同时我想命名我从v中绘制的MyStruct元素(如在循环1中).我能这样做吗?
由于使用共享指针,我经常在我想将它们传递给不必(必须)拥有该对象的函数的情况下运行.因为我知道在函数调用期间对象是有效的,我有四个传递指针的选项:
起初我开始经常使用弱指针(因为我已经有了它们),但是一直锁定它们的开销很烦人并且达到了性能.现在我考虑通过引用传递原始指针或共享指针.有最好的做法吗?
我在阅读另一个问题的绝佳答案,给出了以下具体示例:
char[] array = {'a', 'b', 'c', '\0'};
Run Code Online (Sandbox Code Playgroud)
Thing* t = new Thing[size];
t[someindex].dosomething();
Run Code Online (Sandbox Code Playgroud)
我评论说,作为一种好的做法,您应该添加delete[]第二个示例,因为这是人们忘记导致内存泄漏的位。
但是我不记得您是否需要delete[]一开始。我不认为您会这样做,因为没有,new所以它在堆栈中,但是我不是100%确信那是正确的。
为什么下面的代码显示0,但是如果您注释掉“ std :: string my_string”,它将显示1?
#include <stdio.h>
#include <iostream>
class A {
public:
virtual int foo() {
return 0;
}
private:
std::string my_string;
};
class B : public A {
public:
int foo() {
return 1;
}
};
int main()
{
A* a;
if (true) {
B b;
a = &b;
}
std::cout << a->foo() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我也理解将std :: string更改为std:string *也会导致代码打印1,就像删除if语句一样,尽管我不明白为什么其中任何一个都是正确的。
快点
编辑:这似乎是由于悬空的指针。那么,在Java中执行此类操作的C ++标准模式是什么:
Animal animal;
boolean isDog = false;
// get user input to set isDog …Run Code Online (Sandbox Code Playgroud) 实例:
weapons.push_back(new Pistol());
weapons.push_back(new Rifle());
weapons.push_back(new Shotgun());
Run Code Online (Sandbox Code Playgroud)
析构函数,当第一次删除时,代码中断.当我关闭程序时会发生这种情况.
Brain::~Brain()
{
for (unsigned int i = 0; i < weapons.size(); i++)
{
delete weapons[i]; // this is where the code breaks
}
}
Run Code Online (Sandbox Code Playgroud)
我收到警告:
Unhandled exception at 0x0096371f in D3D10DEMO.exe: 0xC0000005: Access violation reading location 0x000002ce.
Run Code Online (Sandbox Code Playgroud)
武器是这样的:
weapons(vector<Gun*>())
Run Code Online (Sandbox Code Playgroud)
编辑 - 我已经删除了这个问题的大部分代码,但是我也减少了我的程序,以便在一个更小的解决方案中重现问题:
我试图创建一个头文件中定义的自定义对象的向量,然后在实际的cpp文件中初始化它们.我在Visual Studio中遇到以下错误:
error C2976: 'std::vector' : too few template arguments
error C2065: 'Particle' : undeclared identifier
error C2059: syntax error : '>'
Run Code Online (Sandbox Code Playgroud)
在下面的代码中,向量在Explosion.h中定义.
#pragma once
class Particle : public sf::CircleShape {
public:
float speed;
bool alive;
float vx;
float vy;
Particle(float x, float y, float vx, float vy, sf::Color color);
~Particle();
};
Run Code Online (Sandbox Code Playgroud)
#include <SFML/Graphics.hpp>
#include "Particle.h"
Particle::Particle(float x, float y, float vx, float vy, sf::Color color) {
// Inherited
this->setPosition(x, y);
this->setRadius(5);
this->setFillColor(color);
// Player Defined Variables
this->speed …Run Code Online (Sandbox Code Playgroud) 在我的程序中,我有一些用于在游戏中处理射弹的类.
class Projectile
{
bool IsActive;
bool GetActive();
//....
};
class Game
{
std::vector<Projectile*> ProjectilesToUpdate;
//....
};
Run Code Online (Sandbox Code Playgroud)
当然,除此之外还有更多,但我试图保持与当前问题的相关性.
我想使用std :: sort来制作它,以便IsActive == true的所有射弹都处于远端,并且任何非活动的射弹都在最后.
我该怎么做呢?
请看下面的代码.这是一个聪明的指针吗?如果是这样,为什么第一个对象p1悬挂在代码的末尾?(那是p2被析构函数删除但是p1仍然存在,为什么?)
#include <iostream>
#include <vector>
using namespace std;
template <class T> class my_auto_ptr {
T* myptr;
public:
my_auto_ptr(T* ptr = 0) : myptr(ptr) { }
~my_auto_ptr() {
delete myptr;
}
T* operator ->() const {
if (myptr != nullptr) return myptr;
else throw runtime_error("");
}
T& operator* () const {
if (myptr != nullptr) return *myptr;
else throw runtime_error("");
}
T* release() {
T* rptr = myptr;
myptr = 0;
return rptr;
}
};
//----------------------------------
int main() try {
my_auto_ptr<vector<int> …Run Code Online (Sandbox Code Playgroud) 首先我动态分配一个对象:
Object* someObject = new Object();
Run Code Online (Sandbox Code Playgroud)
然后我将该指针的地址插入到向量中:
std::vector<Object**> someVector0;
someVector0.push_back(&someObject);
Run Code Online (Sandbox Code Playgroud)
然后我将居住地址的地址插入someVector0到另一个向量中:
std::vector<Object***> someVector1;
someVector1.push_back(&someVector0[0]);
Run Code Online (Sandbox Code Playgroud)
最后,我将上述地址插入someVector1到另一个向量中:
std::vector<std::vector<Object***>*> someVector2;
someVector2.push_back(&someVector1);
Run Code Online (Sandbox Code Playgroud)
然后我使用获得的向量,现在我需要释放分配的内存:
//Do some stuff
//Free memory
Run Code Online (Sandbox Code Playgroud)
for (int i = 0; i < someVector2.size(); i++) {
for (int j = 0; j < (*someVector2[i]).size(); j++) {
delete *(*(*someVector2[i])[j]);
delete *(*someVector2[i])[j];
delete (*someVector2[i])[j];
}
delete someVector2[i];
}
Run Code Online (Sandbox Code Playgroud)
我曾怀疑这段代码足以解除分配,但是,我在解除分配时遇到了一些问题。我怀疑我可能已经取消引用了 anullptr但我想不出其他任何东西,我删除指针的方式可能有错误吗?
注意:这是我在较大规模的程序中遇到的问题的简化版本,前面提到的向量都不是不必要的,我不想处理任何副本,不要更改向量的类型。
编辑:
您好,在进行了更多研究并听取了评论之后,我已经醒悟了,尽管我认为没有一个人会认为我的代码以任何方式合理,但我强烈敦促任何可能认为这是一种有效方法的人做任何不做的事情。正如评论已经指出的那样,我对解决方案的尝试表明我不知道自己在做什么,所以请不要这样做;它实际上是无法维护的。相反,正如另一条评论已经指出的那样,请使用智能指针或真正了解代码中发生的情况。