1

I'm reading a book of Herbert Schildt (2002) and learning about virtual functions. There is one example program there that the author assures is compilable. However, compiler doesn't compile it. Compiler says the problem is in

shapes[0] = &Square(2.0);

It may have something to do with the array of pointers to objects, and maybe with C++11 (if so, I don't understand why to disable this functionality of arrays). The program is a little long, so I cut it and simplified it to isolate the problem and to make it simple to read.

#include <iostream>
using namespace std;

// Base class for two-dimensional objects:
    class TwoDShape {
    double side;
    char name[20];
public:
    TwoDShape(double x) {
        side = x;
    }
    double getSide() { return side; }
    void setSide(double w) { side = w; }
    virtual double area() = 0;
};

// Derived class for Squares:
class Square : public TwoDShape {
public:
    Square(double x) : TwoDShape(x) { };
    double area() { return getSide() * getSide(); }
};

int main() {
    TwoDShape *shapes[3];

    shapes[0] = &Square(2.0);
    shapes[1] = &Square(6.0);
    shapes[2] = &Square(9.0);

    return 0;

}

Anselmo GPP
  • 425
  • 2
  • 21
  • 1
    You can't take the address of a temporary object. What about `shapes[0] = new Square(2.0);`, etc. ? – DimChtz Nov 02 '17 at 16:40
  • 6
    *Why* are you learning C++ from a 15 year old book? – Jesper Juhl Nov 02 '17 at 16:40
  • 3
    This never worked. You cannot take addresses from rvalues. And even if you could, it would be harmful as those are temporary objects that get deleted as soon as the next statement is executed. – Jodocus Nov 02 '17 at 16:42
  • 4
    Why are you learning C++ from Herb Schildt? He's known for sloppiness. – Pete Becker Nov 02 '17 at 16:42
  • It looks like the problem is that `shapes` is being populated by the addresses of temporary objects. If you create specific objects (e.g., `Square a(2.0); shapes[0] = &a;`, you'll be able to compile. – Max Lybbert Nov 02 '17 at 16:42
  • 4
    Current C++ standard is [C++14](https://en.wikipedia.org/wiki/C%2B%2B14). The previous [C++11](https://en.wikipedia.org/wiki/C%2B%2B11) brought huge changes. The next [C++17](https://en.wikipedia.org/wiki/C%2B%2B17) will be published in a few weeks. **You are losing your time learning an obsolete variant of C++** – Basile Starynkevitch Nov 02 '17 at 16:42
  • See also http://en.cppreference.com/w/cpp – Basile Starynkevitch Nov 02 '17 at 16:43
  • 4
    IMHO that is a _bad_ C++ book, you might want to check out the [C++ book list](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – miradulo Nov 02 '17 at 16:44
  • 1
    See http://stason.org/TULARC/webmaster/lang/c-cpp-faq/16-Why-do-many-experts-not-think-very-highly-of-Herbert-Schildt-s-books.html – Thomas Matthews Nov 02 '17 at 16:45

1 Answers1

3

Well, old C++ compilers written around 2000s (at least, some of them) actually allow that. However, it's a clear mistake to use such construction here.

Square(x,y) makes a temporary object, which gets deleted immediately after creation. Thus all stored pointers become invalid, and the program doesn't crash only because they are not used anymore.

Therefore modern C++ compilers treat this as an error ("taking address of temporary") and refuse to generate code.

Matt
  • 13,674
  • 1
  • 18
  • 27
  • Thanks, to you and the other people who answered my question. That is the problem. – Anselmo GPP Nov 02 '17 at 17:27
  • Thank you. And thanks to the other people who answered my question. That is a temporary object, althought Schildt said it wasn't. I was aware of Herbert Schildt "sloppiness" but I thought his book was a good one and that C++ didn't change too much in 15 years. This is not the first issue I have with his example programs. I should move to more recent sources. – Anselmo GPP Nov 02 '17 at 17:33
  • @HansGP `I thought his book was a good one and that C++ didn't change too much in 15 years` Well, in this particular case it was just a minor "security" upgrade: both syntax and semantics remain the same, but taking address of a temporary is explicitly prohibited now. `That is a temporary object, althought Schildt said it wasn't` But it is. I even checked it against BC++ 5.5 and OpenWatcomC++ 1.9, and it works just as expected. I must say, I haven't read this particular book, but I remember some of Schildt's other books, and they all were absolutely horrible. – Matt Nov 02 '17 at 19:23