Newsgroup: it.comp.lang.c++
Titolo: exception copy ctor

Salve,
    struct Ex {
        Ex() {};
    private:
        Ex(const Ex&);
    };
    int main() {
        try {
            throw Ex();
        } catch (Ex& e) {
            ;
        }
    }
alla throw, il compilatore mi dice che Ex::Ex(const Ex&) è privato.
Se sposto Ex(const Ex&) in public, cioè 
    struct Ex {
        Ex() {};
        Ex(const Ex&);
    };
il programma viene compilato ed eseguito senza problemi.
Perché?
Grazie
PS: il compilatore è il g++ 3.4
-- 
int

Perche' il compilatore e' tenuto a fare una copia dell'oggetto lanciato
per "stivarlo" in un posto permanente. Altrimenti sarebbe il primo
oggetto distrutto durante lo svolgimento dello stack.
Ciao,
Nicola


Ok, ma cosa chiamerebbe per farne la copia, dal momento che ho
dichiarato il copy ctor ma non l'ho definito, e non ho errori di link?
-- 
int

int i=0 0; wrote:

magari ottimizza e non fa la chiamata, ma comunque deve essergli 
possibile poter fare la copia (e se lo dichiari privato glielo impedisci).
-- 
si prepara direttamente nel bicchiere basso detto "tumbler basso". Tre o 
quattro cubetti di ghiaccio, aggiungere il gin, il martini rosso, il 
bitter campari e mescolare. Guarnire con una fetta d'arancia.



Esempio similare:
struct X
{
   X(int) {}
private;
   X(const X&);
};
X x = X(1);  // ERRORE
X x(1);      // OK
struct Y
{
   Y() {}
   Y(const Y&);
};
Y y = Y(1);  // OK
Y y(1);      // OK
-- 
Horst

 Y y(1);      // OK
Quindi, se ho capito dall'esempio, rendendo pubblic il costruttore di
copia ma non definendolo, viene usata la definizione del costruttore di
copia di default?
Ora, dato il comportamento del seguente sorgente compilabile:
#include<iostream>
using std::cout;
using std::endl;
struct X // private copy ctr
{
    X() { cout << "X::X()" << endl; }
    private: X(const X&); // :9
};
struct Y // public copy ctr, no def
{
    Y() { cout << "Y::Y()" << endl; }
    Y(const Y&);
};
struct Z // public ctr, with def
{
    Z() { cout << "Z::Z()" << endl; }
    Z(const Z&) { cout << "Z::Z(const Z&)" << endl; }
};
int main() {
    try {
        // throw X(); // :26
        // :9 error: `X::X(const X&)' is private
        // :26 error: within this context
        // :9 error: `X::X(const X&)' is private
        // :26 error: within this context
    } catch (X& e) {
        ;
    }
    try {
        // throw X(); // :35
        // :9 error: `X::X(const X&)' is private
        // :35 error: within this context
        // :9 error: `X::X(const X&)' is private
        // :35 error: within this context
        // :9 error: `X::X(const X&)' is private
        // :42 error: within this context
    // } catch (X e) { // :42
        // :9 error: `X::X(const X&)' is private
        // :42 error: within this context
    } catch (...) {
        ;
    }
    try {
        throw Y(); // Y::Y()
    } catch (Y& e) { // :50
        ;
    }
    try {
        // throw Y(); // :54
        // /tmp/ccGD6mJ0.o(.text+0x225): In function `main':
        // : undefined reference to `Y::Y(Y const&)'
        // collect2: ld returned 1 exit status
    } catch (Y e) {
        ;
    }
    try {
        throw Z(); // :62 Z::Z()
    } catch (Z& e) {
        ;
    }
    try {
        throw Z();  // Z::Z()
    } catch (Z e) { // :68 Z::Z(const &Z)
        ;
    }
}
a) Per X si cerca di invocare più volte il copy ctr, ma essendo privato
non si può fare nulla.
b) Per Y il copy ctr è accessibile ma non definito, quindi dovrebbe
usare la definizione di default, e sembra lo faccia per la riga 50
( catch Y& ) ma non per la riga 54 ( catch Y ), dove il copy ctr di
default sembra non venga trovato. Perché?
c) Per Z viene invocato il copy ctr da me definito, ma solo nel caso a
riga 68 ( catch Z ) e non a riga 62 ( catch Z& ). Perché?
Saluti
-- 
int

 riga 68 ( catch Z ) e non a riga 62 ( catch Z& ). Perché?
Ottimizzazione...
-- 
Horst

 la legalitą non puņ dipendere da una ottimizzatione.
... che mi ha aperto gli occhi 8-)
Saluti
-- 
int