📄 class.cc
字号:
<< key << "--perhaps a duplicated CTOR call" << endl; abort(); } // go thru the list of children and correct their // parent class descriptors for (std::set<std::string>::iterator i=children_->begin(); i!=children_->end(); i++) { (*all_)[*i]->change_parent((*all_)[key],this); } delete (*all_)[key]; unresolved_parents_->erase(key); if (unresolved_parents_->size() == 0) { delete unresolved_parents_; unresolved_parents_ = 0; } } (*all_)[key] = this;}ClassDesc::~ClassDesc(){ // remove references to this class descriptor if (children_) { for (std::set<std::string>::iterator i=children_->begin(); i!=children_->end(); i++) { if (all_->find(*i) != all_->end()) { (*all_)[*i]->change_parent(this,0); } } } // delete this ClassDesc from the list of all ClassDesc's std::string key(classname_); all_->erase(key); // if the list of all ClassDesc's is empty, delete it if (all_->size() == 0) { delete all_; all_ = 0; delete[] classlib_search_path_; classlib_search_path_ = 0; } // delete local data delete[] classname_; if (children_) delete children_;}ClassDesc*ClassDesc::class_desc(const type_info &ti){ if (type_info_all_->find(type_info_key(&ti)) == type_info_all_->end()) return 0; return (*type_info_all_)[type_info_key(&ti)];}std::map<std::string,ClassDescP>&ClassDesc::all(){ if (!all_) { ExEnv::errn() << "ClassDesc::all(): all not initialized" << endl; abort(); } return *all_;}ClassDesc*ClassDesc::name_to_class_desc(const char* name){ std::string key(name); if (all_->find(key) == all_->end()) return 0; return (*all_)[key];}DescribedClass*ClassDesc::create() const{ if (ctor_) return (*ctor_)(); return 0;}DescribedClass*ClassDesc::create(const Ref<KeyVal>&keyval) const{ DescribedClass* result; if (keyvalctor_) { result = (*keyvalctor_)(keyval); } else result = 0; return result;}DescribedClass*ClassDesc::create(StateIn&statein) const{ if (stateinctor_) return (*stateinctor_)(statein); return 0;}voidClassDesc::change_parent(ClassDesc*oldcd,ClassDesc*newcd){ parents_.change_parent(oldcd,newcd);}voidClassDesc::list_all_classes(){ ExEnv::out0() << "Listing all classes:" << endl; for (std::map<std::string,ClassDescP>::iterator ind=all_->begin(); ind!=all_->end(); ind++) { ClassDesc* classdesc = ind->second; ExEnv::out0() << "class " << classdesc->name() << endl; ParentClasses& parents = classdesc->parents_; if (parents.n()) { ExEnv::out0() << " parents:"; for (int i=0; i<parents.n(); i++) { if (parents[i].is_virtual()) { ExEnv::out0() << " virtual"; } if (parents[i].access() == ParentClass::Public) { ExEnv::out0() << " public"; } else if (parents[i].access() == ParentClass::Protected) { ExEnv::out0() << " protected"; } if (parents[i].classdesc() == 0) { ExEnv::errn() << endl << "ERROR: parent " << i << " for " << classdesc->name() << " is missing" << endl; abort(); } const char *n = parents[i].classdesc()->name(); ExEnv::out0() << " " << parents[i].classdesc()->name(); } ExEnv::out0() << endl; } std::set<std::string>* children = classdesc->children_; if (children) { ExEnv::out0() << " children:"; for (std::set<std::string>::iterator pind=children->begin(); pind!=children->end(); pind++) { ExEnv::out0() << " " << (*pind); } ExEnv::out0() << endl; } }}DescribedClass* ClassDesc::create_described_class() const{ return create();}// Returns 0 for success and -1 for failure.intClassDesc::load_class(const char* classname){ // See if the class has already been loaded. if (name_to_class_desc(classname) != 0) { return 0; } #if HAVE_DLFCN_H // make a copy of the library search list char* path = new char[strlen(classlib_search_path_) + 1]; strcpy(path, classlib_search_path_); // go through each directory in the library search list char* dir = strtok(path,":"); while (dir) { // find the 'classes' files char* filename = new char[strlen(dir) + 8 + 1]; strcpy(filename,dir); strcat(filename,"/classes"); ExEnv::outn() << "ClassDesc::load_class looking for \"" << filename << "\"" << endl; FILE* fp = fopen(filename, "r"); delete[] filename; if (fp) { // read the lines in the classes file const int bufsize = 10000; char buf[bufsize]; while(fgets(buf, bufsize, fp)) { if (buf[0] != '\0' && buf[strlen(buf)-1] == '\n') { buf[strlen(buf)-1] = '\0'; } char* lib = strtok(buf," "); char* testclassname = strtok(0," "); ExEnv::outn() << "lib = \"" << lib << "\"" << endl; while(testclassname) { ExEnv::outn() << "classname = \"" << testclassname << "\"" << endl; if (strcmp(testclassname,classname) == 0) { // found it char* libname = new char[strlen(lib) + strlen(dir) + 2]; strcpy(libname, dir); strcat(libname, "/"); strcat(libname, lib); // load the libraries this lib depends upon // i should look in the library's .dep file to // get the dependencies, but this makes it a little // difficult to make sure the same library doesn't // get loaded twice (which is important) so for now // i'll just wait until after i load the library and // then look in the unresolved parents set // and load parents until nothing is left // load the library ExEnv::outn() << "loading \"" << libname << "\"" << endl; dlopen(libname, RTLD_LAZY); // load code for parents while (unresolved_parents_ && unresolved_parents_->size()) { load_class((*unresolved_parents_->begin()).c_str()); } fclose(fp); delete[] path; // make sure it worked. if (name_to_class_desc(classname) == 0) { ExEnv::errn() << "load of \"" << classname << "\" from \"" << libname << "\" failed" << endl; delete[] libname; return -1; } ExEnv::outn() << "loaded \"" << classname << "\" from \"" << libname << "\"" << endl; delete[] libname; return 0; } testclassname = strtok(0," "); } } fclose(fp); } dir = strtok(0, ":"); } delete[] path;#endif // HAVE_DLFCN_H ExEnv::outn() << "ClassDesc::load_class(\"" << classname << "\"): load failed" << endl << "Either \"" << classname << "\" is an invalid class name or the code" << endl << "for \"" << classname << "\" was not linked into the executable." << endl; return -1;}////////////////////////////////////////////////////static ClassDesc DescribedClass_cd( typeid(DescribedClass),"DescribedClass");DescribedClass::DescribedClass(){}DescribedClass::DescribedClass(const DescribedClass&) {}DescribedClass& DescribedClass::operator=(const DescribedClass&){ return *this;}DescribedClass::~DescribedClass(){}ClassDesc*DescribedClass::class_desc() const{ return ClassDesc::class_desc(typeid(*this));}const char* DescribedClass::class_name() const{ return class_desc()->name();}int DescribedClass::class_version() const{ return class_desc()->version();}voidDescribedClass::print(ostream &o) const{ o << indent << "Object of type " << class_name() << endl;}ostream &operator <<(ostream&o, const RefBase &ref){ DescribedClass *dc = dynamic_cast<DescribedClass*>(ref.parentpointer()); if (dc) { dc->print(o); } else { o << indent << "reference to null" << endl; } return o;}#ifdef EXPLICIT_TEMPLATE_INSTANTIATIONtemplate class std::map<std::string,ClassDescP>; template class std::map<std::string,int>;template class std::set<std::string>;#endif/////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "CLJ"// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -