GAVD
GAVD

Reputation: 2134

Taking address of temporary [-fpermissive]

I know this question is already answered. But I just want to confirm what I understand.

Here is my snippet code. It comes from this.

#include <iostream>
using namespace std;

class Base
{
    void a() { cout << "a  "; }
    void c() { cout << "c  "; }
    void e() { cout << "e  "; }

    // 2. Steps requiring peculiar implementations are "placeholders" in base class
    virtual void ph1() = 0;
    virtual void ph2() = 0;

  public:

    // 1. Standardize the skeleton of an algorithm in a base class "template method"
    virtual ~Base() = default;
    void execute()
    {
        a();
        ph1();
        c();
        ph2();
        e();
    }
};

class One: public Base
{
    // 3. Derived classes implement placeholder methods
    /*virtual*/ void ph1() { cout << "b  "; }
    /*virtual*/ void ph2() { cout << "d  "; }
};

class Two: public Base
{
    /*virtual*/ void ph1() { cout << "2  "; }
    /*virtual*/ void ph2() { cout << "4  "; }
};

int main()
{
  Base *array[] =
  {
      &One(), &Two()
  };
  for (int i = 0; i < 2; i++)
  {
      array[i]->execute();
      cout << '\n';
  }
}

When I compiled, it gives the error as the title:

error: taking address of temporary [-fpermissive]
&One(), &Two()
error: taking address of temporary [-fpermissive]
&One(), &Two()

So, I try to find in the internet. And as they said:

&A() is creating a temporary object which gets destructed on exit of the full expression automagically...

When I changed error line

&One(), &Two()

to

new One(), new Two()

Then, it works.

But, how I make the origin code works like the author wrote? Should I use delete like

delete array[i];

Upvotes: 0

Views: 954

Answers (1)

Trollliar
Trollliar

Reputation: 866

With modern C++ features (11 and above) you can handle such polymorphic arrays with std::vector<std::unique_ptr<Base>>. vector allows automatic destruction and extension, and unique_ptr will destroy the object on its own destruction:

std::vector<std::unique_ptr<Base>> array;
array.emplace_back(new One());
array.emplace_back(new Two());
for(auto &p : array)
    p->execute();
// no explicit cleanup is required here

You can choose other smart pointer classes as vector's elements, or even use std::array as fixed size container, but general idea is same for all approaches:

Try not to handle memory management manually, use STL primitives for such low-level actions.

Upvotes: 2

Related Questions