开发者

Stack object reinstantiation in C++

开发者 https://www.devze.com 2023-01-28 04:53 出处:网络
I would like to use the same variable but I want to reinstantiate it. How do开发者_高级运维 I do it in c++?

I would like to use the same variable but I want to reinstantiate it. How do开发者_高级运维 I do it in c++? Here is a simple example. I try to reinstantiate t1 but it doesn't compile. (Notice t1 is stored in the stack. I'm not asking how to do dynamic memory allocation)

class Table
{
  private int feet;
  public Table(int x)
  {
    feet=x;
  }
}

Table t1(3);
t1(4);


The answer is a wonderful language feature called assignment.

In short, you can change the value of a variable – even a variable of a type you have defined yourself – by using the = symbol.

As a matter of fact your code is already using assignment, namely in the constructor.

In the example below I've replaced that original code's assignment with an initializer, because initializers are generally preferable (choose them when there is no good reason to use assignment for initializating members).

The assignment that updates the value of t1, effectively "reusing" t1, can go like this:

class Table
{
private:
    int feet;
public:
    Table( int x ): feet( x ) {}
};

Table t1( 3 );
t1 = Table( 4 );

Note 1: it's possible to define a type so that assignment is prohibited.

Note 2: since you have defined a conversion constructor, one that accepts a single argument, and since that constructor is not explicit, the assignment above can be expressed more simply (but perhaps less clearly) as …

t1 = 4;

… which results in exactly the same.

Note 3: your code as presented would not have compiled, it was just "like" C++, it was not C++. I've fixed the errors (I think, but I didn't bother to run it through a compiler). But in general it's not always possible to know or even guess whether errors in the presented code have something to do with the question, so please copy and paste real code.

Cheers & hth.,


I'd suggest using the swap idiom instead, but if you really want to recreate a new object in the same variable, use placement new:

Table t1(3);
t1.~Table();
new (&t1) Table(4);

Placement new simply constructs an object in memory you provide, without doing any allocation.

If you decide to go with swap, you'll have to write the swap function, and then to do the reinstantiation:

Table t1(3);
Table(4).swap(t1);


Why do you want to reinstanciate ? That's not RAII.

Instanciation is about getting space for object, then calling constructor. If you just want to change the member values, or call some method, create some init method and call it both from constructor and when you want to reset object. This works in simple cases bus is not exactly like a constructor. Some things (like initializing reference members) can be done only in initialization list that exists only in constructor.

And obviously you should take some care, as destructors should be called for member variables before reallocating them.

Placement new would also works, but it looks like overkill, you won't get more with it than through calling a simple method to reset object. And it's dangerous as it can lead to very tricky bugs.

SWAP Idiom as suggested by Ben Voight is probably the best choice you have if you go on the overloading of assignement operator track.

My advice on reinstanciating is don't.

What's the problem with using a brand new instance and leaving the old one alone ? Reusing the same variables for different tasks was already a bad idea with C as it makes compiler optimization harder. It still is with C++, and it is also dangerous as you may easily forget to call destructor of the first object and go into troubles.

There is cases where you would need to do that, like if you took the address of the object, and want to change it's members. But in such cases it's probably better to change your code to avoid doing that anyway. I can see of no real case where this would be necessary. If there is, I'm interested to know about.


The prefered answer doesn't solve the problem quite well. The assignment doesn't actually reinstantiate the object, it just does an assignment. In the example, if feet were to be const, the solution won't compile.

A trickier solution would be use "Placement new"/"Placement syntax" like:

Table t1(3);
t1.~Table();
new (&t1) Table(4);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号