2016-03-26 21 views
-1
Ben normalde çalışan bir kod parçası var

giriş sonra beklenmedik şekilde sona ama durum işleme eklediğinizde kırılır. Ben bir acemi ve burada (korumalar gösterilmeyen içerir bakacak olursak)programı catch bloğu

Bu kod çalışır kod: plane.h olarak

:

#include "vector.h" //which, like point.h, inherits from orderedpair.h 
class Plane { 
    public: 
     Plane(const std::string &label); 
     Plane(const Plane &); 
     virtual ~Plane(); 

     void insert(const OrderedPair &); 
     void label(const std::string & label); 
     std::string label() const {return _label;} 

    protected: 
     std::string _label; 
     bool operator==(const Plane &rhs) const {return label() == rhs.label();} 
     bool operator<(const Plane & rhs) const {return label() < rhs.label();} 
}; 

plane.cpp olarak

#include <set> 
Plane::Plane(const std::string &label) : _label(label) { 
    getUniverse().insert(this); 
} 

/*GLOBAL OBJECTS*/ 

extern std::set<Plane *>& getUniverse() { 
    static std::set<Plane *>universe; 
    return universe; 
} 

extern Plane& getDefaultPlane() { 
    static Plane Default("Default"); 
    return Default; 
} 

void printworld() { 
    for (auto i : getUniverse()) 
     std::cout << (*getUniverse().find(i))->label() << std::endl; 
} 

ve ana içinde :

//MinGW32 4.9 Code::Blocks 16.01 Windows Vista(!!) 64bit -std=C++11 
#include <iostream> 
#include "vector.h" //includes point.h which includes orderedpair.h 
#include "plane.h" 

using namespace std; 

namespace { 
    struct Initializer {; 
     Initializer(); 
    }; 
} 

int main() { 

static Initializer init; 
Point A("A", 1, 1); 

Plane P("P"); 
Plane duplicate("Default"); 

printworld(); 
return 0; 
} 

Initializer::Initializer() 
{ 
    // Trigger construction of the default Plane 
    getDefaultPlane(); 
} 

Sonra plane.h içinde istisna bulunmaktadır ve üstünde aşağıdakileri ekleyin:

class E : public std::exception { 
    const char *msg = nullptr; 
public: 
    E(const char *m) throw() : msg(m) {} 
    const char *what() const throw() {return msg;} 
}; 
const E DuplicateObj("Object already exists!\n"); 

O derlenmiş ve çalışan bir sorun olmadan.

Plane::Plane(const std::string &label) : _label(label) { 
    for (auto i : getUniverse()) { 
      if ((*getUniverse().find(i))->label() == _label) throw DuplicateObj; 
    } 
    getUniverse().insert(this); 
} 

ve (atış tetiklemesi önlemek için) ana yinelenen düzlemde örneğinin açıklama: Sonra (emin etiket önce kullanılmamış olan hale getirmek için) bu şekilde Plane yapıcı değiştirin. Derler ve çalışır, sorun yok.

sonra ana bir deneme/yakalama bloğunda nesne örneğinin çizgileri sarın:

try { 
    Point A("A", 1, 1); 
    Plane P("P"); 
    //Plane duplicate("Default"); 
} 
catch (const E& e) { 
    cerr << e.what() << endl; 
} 
catch (const exception &e) { 
    cerr << e.what() << endl; 
} 

Aşağıdaki sonuçla çöker ama derler:

Process returned -1073741819 (0xC0000005) execution time : 9.537 s 
Press any key to continue. 
+0

Özel bir varsayılan kurucuya ihtiyacınız yoktur. Başka bir kurucu sağladığınızda, varsayılan olanı bastırılacaktır. –

+1

Özel durumu attığınız kodu göremiyorum. –

+0

İdeal olarak, eksiksiz ve tamamlanabilir bir şey gönderin. – kec

cevap

0

istisnalar bir sorun değil mi .

O pointer ve kapsamı bir sorun.

yanılmıyorum edin.

Sizin Düzlem yapıcı eki (getUniverse().insert(this);) statik bir küresel sette (getUniverse() yılında static std::set<Plane *>universe;) içinde this işaretçi.

Sonra main() (printworld()) son talimatında küresel kümesini kullanır. try/catch blokların giriş önce

, Plane P("P"); nesne alanı tam main() fonksiyonudur; P işaretçisi printworld aradığınızda geçerli bir işaretçidir.

Ama P kapsamı sadece try bloktur

try { 
    Plane P("P"); 
    // end of P scope 
} 

// P is out of scope; the pointer to P, in universe, is invalid 

printworld(); // use of a invalid pointer to P 

yazarken; Yani, try bloğundan printworld() aradığınızda, universe yok edilen bir nesnenin işaretçisini içerir.

Crash!

P.S. .: benim kötü İngilizce için üzgünüm.

+0

Bu tam olarak sorun! Sorunun kapsam ile ilgili olduğunu anladım, ama tam olarak ne olduğunu anlayamadım. Kafasına çivi vurdun! Çok teşekkürler! Bunu, P yığınını ilan etmekten başka bir şeyden kurtulmanın bir yolu var mı? @ max66 –

+0

Başka yollar olup olmadığını bilmiyorum. Sadece 'evren' işaretçileri kullandığını unutmayın, bu nedenle bu işaretçilerin geçerli olduğundan emin olmalısınız. Bu durumda 'new' /' delete' komutunu kullanabilir ya da 'try' bloğundaki' printworld' kullanabilirsiniz. – max66