2014-12-05 159 views
0

C++:对象可以被更早地销毁,以使其存储内存被后续对象重用吗?对象是否可以被更早的销毁,以使其存储内存可以被后续对象重用?

在C++代码一个段,在所述第一半部分,一个对象,使用B; 在下半部分,创建和使用对象c,d。

由于物体A,B占用大量的内存,我想手动销毁对象A,B上半年部分结束的时候。

我知道我可以使用新的,删除去实现它。

但是,如果我不使用新的,但还是要销毁对象较早(这意味着,范围的结束时间之前),我可以手动调用析构函数摧毁它?所以这部分内存可以重用于对象c和d。 (我不需要来释放内存,因为重用是罚款

下面是一个伪代码:。

monsterClass a, b; 
dragonClass c, d; 
int i,j,k,l; 

a = monsterClass(1000, 2000); 
b = monsterClass(2000, 3000); 
i = processMethod1(a, b); 
j = ...; 
k = ...; 
l = ...; 


// here, I want to destroy a, b, since they are not used any more, while occupy memory. 
// The above half part and the below half part use many common variables. 
// So it seems scope {} method makes it inconvenient, 
// since I don't want to create a function with too many parameters. 
// I don't want to use new or delete here. I hope it looks simple and not prone to error 
// So can I use: ~a, ~b here? 

c = dragonClass(400, 3000); 
d = dragonClass(500, 4000); 
processMethod2(c, d, i); 
j = ...; 
k = ...; 
l = ...; 

[更新1]所以,大多数人建议使用范围,这是一个很好的方式 我还是很好奇,我可以使用〜a和〜b吗? 我觉得这似乎是一种可行和方便的方式。

[Update 2]我想到了另一种情况,在这种情况下,不同变量的作用域是交织在一起的!就像这样:a的范围有b的作用域的重叠,但它们不包括关系。它是部分重叠的关系。 在这种情况下,这是否意味着使用范围是不可能的? 最后的手段是使用新的和删除,对吧?

+0

请添加代码的例子来解释为什么你必须销毁对象_before scope_其结束的时间。你总是可以添加额外的'{}'来定义更小的范围。 – timrau 2014-12-05 17:03:07

+1

[您可以手动调用原始对象的析构函数,然后使用放置'new'在该内存之上创建一个新对象](http://stackoverflow.com/questions/2494471/c-is-it-可能对呼叫一个构造函数 - 直没有新)。如果你这样做,清楚地记录事情,因为它可能会严重混淆/误导代码的读者。 – Cornstalks 2014-12-05 17:04:16

+0

你能否将这两个部分作为单独的功能实现?或在一个函数内单独的块?这比手动控制要简单得多(尽管如果你真的需要的话,这在某种程度上是可能的)。 – 2014-12-05 17:09:01

回答

1

通过使用大括号可以手动控制堆栈中对象的生存期。

void foo() 
{ 
    int x = 5; 
    int y = 2; 

    {   // This introduces a new scope 
    int z = 3; 
    }   // After this brace, z is now out of scope 

    int a = x + y; 
} 

但是请注意,一旦变量超出范围,当再次使用此内存时未指定。仅仅因为我宣布了名为a的另一个int,并不意味着它将被分配到以前的地址z

+0

我不在乎新变量是否完全利用旧变量的内存。但我希望编译器足够聪明,可以使用废弃变量的内存。现代编译器是这样吗? – user1914692 2014-12-05 17:22:45

+0

是的,一旦变量超出范围,使用我展示的方法或Mike或erenon的解决方案,该内存就可以免费用于某些其他对象。我只是想确保你知道那个特定的位置不一定会立即被重用。 – CoryKramer 2014-12-05 17:24:42

3

使用布局新和手动调用析构函数:

{ 
    char memory[std::max(sizeof(A),sizeof(B))]; 

    A* pA = new (memory) A(); 
    // use `pA` 
    pA->~A(); // destruct A 

    B* pB = new (memory) B(); 
    // use `pB` 
    pB->~B(); // destruct B 
} // `memory` goes out of scope 

我建议阅读的新运营商这个优秀的资源:http://en.cppreference.com/w/cpp/language/new

+0

这听起来有点复杂。我希望使用一个简单的。 – user1914692 2014-12-05 17:23:11

2

你可以把它分解成更小的功能:

void part1() { 
    monsterClass a, b; 
    a = monsterClass(1000, 2000); 
    b = monsterClass(2000, 3000); 

    processMethod1(a, b); 
} 

或块内的较大函数

{ 
    monsterClass a, b; 
    // and so on 
} 
{ 
    dragonClass c, d; 
    // and so on 
} 

或使用的临时

processMethod1(
    monsterClass(1000, 2000); 
    monsterClass(2000, 3000); 
); 

如果你正在做的事情很复杂,这些都不是合适的,你可以用工会,或放置新陷入混乱;细节会很烦琐,具体取决于你奇怪的要求是什么。

+0

上面的半部分和下面的半部分使用了许多共同的变量。所以它看起来范围{}方法使它很不方便,因为我不想创建一个参数太多的函数。我更愿意使用手动管理它。可能吗? – user1914692 2014-12-05 17:21:28

+0

@ user1914692:我不认为这会使它特别不方便。你必须在内部块之外声明公共变量;或者可能将它们包装在一个类中,并将其传递给函数。正如我所说的那样,手工管理可能有工会或职位 - 新的可能;但很烦琐,而且要看你的奇怪要求的细节。在诉诸这种古怪之前,我会努力使用传统的示波器。 – 2014-12-05 17:25:19

+0

你是对的。你的答案类似于timrau的答案。我可以将常用变量放在这些块之外。 – user1914692 2014-12-05 17:31:23

1

由于您的代码段,你可以写为

int i,j,k,l; 

{ 
    monsterClass a(1000, 2000); 
    monsterClass b(2000, 3000); 
    i = processMethod1(a, b); 
    j = ...; 
    k = ...; 
    l = ...; 
} 

// here, you want to destroy a, b, since they are not used any more, while occupy memory. 

dragonClass c(400, 3000); 
dragonClass d(500, 4000); 
processMethod2(c, d, i); 
j = ...; 
k = ...; 
l = ...; 

// you could use the same technique if there are still e, f or so 
+0

谢谢。我想到另一种情况。在这种情况下,不同变量的范围是交织在一起的!就像这样:a的范围有b的范围的重叠,但是它们不包括关系。它是部分重叠的关系。在这种情况下,最后的手段是使用新的和删除,对吗? – user1914692 2014-12-05 20:42:17

+0

@ user1914692肯定。 – timrau 2014-12-06 03:15:59

相关问题