> But ... classes without copy/assignment operator aren't copied
> byte-by-byte, but member-by-member[1]. So, for string members the
> string copy constructor is used. Again, the code looks right to me
> as it is.
>
> m.
>
>
> [0] Bjarne Stroustrup, "The C++ Programming Language", 2nd edition,
>     p. 582, "r.12.8 Copying Class Objects"
>

It's a pity I am at home & sick, and without the book. I don't know
what is written in the section you refer to.

Therefore the only
thing I can do is try to code it and see what's happening. I tried to
amend the snippet with a 3rd case, which crashes on my machine, and,
AFAIU, precisely because the default member copy semantics is byte-by-byte
on my gcc (now it could well be that this is not the std, but I was pretty
happy about gcc compliance so far). What do you think?

BTW, maybe you meant to say that if I don't provide a copy ctor
in the derived class, then the parent's copy ctor is nevertheless
involved on the parent portion? I know *that*, but it doesn't cover
copying of the derived class' instance data.

#include <exception>
#include <iostream>
#include <string>
using namespace std;

struct E : exception {
        E() : _msg("DEFAULT") { cout << "E::E()" << endl; }
        E(const char* s) : _msg(s) {
                cout << "E::E(const char*" << s << ")" << endl; }
        E(const E& e) : _msg(e._msg + "(clone)") {
                cout << "E::E(const E&" << e._msg << ")" << endl; }
        E& operator=(const E& e) {
                cout << "E::operator=(" << e._msg << ") assigned over " << _msg 
<< endl;
                _msg = e._msg + "(assigned)";
                return *this;
        }
        virtual ~E() throw() { cout << "E::~E() " << _msg << endl; }
        const char* what() const throw() { _msg.c_str(); }
        string _msg;
};

struct EE {
        E e;
        EE(const char* s) : e(s) { cout << "EE::EE(" << s << ")" << endl;}
        virtual ~EE() throw() { cout << "EE::~EE(" << e._msg << ")" << endl;}
};

void foo(int i) throw(exception&)
{
        cout << "foo entering" << endl;
        E unused("xUNUSED");
        switch (i) {
                case 0:
                        break;
                case 1:
                        throw E("x1");
                case 2: {
                        E weird("x2");
                        throw weird;
                }
                case 3: {
                        EE default_cloned("x3");
                        throw default_cloned; // CRASH as EE::e is never cloned 
properly
                }
        }
        cout << "foo exiting" << endl;
}

int main()
{
        for (int i = 0; i < 4; i++) {
                try {
                        foo(i);
                }
                catch (E& e) {
                        cout << "Caught " << e.what() << endl;
                }
        }
        return 0;
}



_______________________________________________
Flightgear-devel mailing list
[email protected]
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d

Reply via email to