Я пытаюсь создать класс Animal, с некоторыми подклассами, которые имеют интерфейсный метод newObject (), возвращающий новый экземпляр self:
Animal.h
class Animal{
public:
virtual Animal* newObject()=0;
};
и я пытаюсь реализовать шаблон реестра с классом AnimalRegister, который хранит сопоставление между именем класса и экземпляром класса:
AnimalRegister.h
#include <map>
class Animal;
class AnimalRegister{
public:
static void* add(const char* name,Animal* a);
static Animal* get(const char* name);
protected:
static std::map<const char*,Animal*> m;
};
AnimalRegister.cpp
#include "AnimalRegister.h"#include <stdio.h>
std::map<const char*,Animal*> AnimalRegister::m;
void* AnimalRegister::add(const char* name,Animal* a){
m[name]=a;
printf("%s registered\n",name);
return NULL;
}
Animal* AnimalRegister::get(const char* name){
return m[name];
}
когда я добавляю подкласс Cat:
Cat.h
#include "Animal.h"class Cat : public Animal{
public:
virtual Animal* newObject();
protected:
static void* Cat_;
};
Cat.cpp
#include "Cat.h"#include <stdio.h>
#include "AnimalRegister.h"
void* Cat::Cat_=AnimalRegister::add("Cat",new Cat());
Animal* Cat::newObject(){
printf("Cat::newObject");
return new Cat();
}
линия
void* Cat::Cat_=AnimalRegister::add("Cat",new Cat());
сопоставляет строку «Cat» с экземпляром Cat, так что позже я смогу создать нового Cat по имени:
Animal* a=AnimalRegister::get("Cat")->newObject();
вместо
if(string(name)=="Cat"){
return new Cat();
}
это нарушает принцип открытого закрытого типа при добавлении нового подкласса.
но когда я пытаюсь проверить код выше:
#include "Cat.h"#include "AnimalRegister.h"int main(){
printf("#1");
Animal* a1=AnimalRegister::get("Cat");
printf("#2");
Animal* a2=a1->newObject();
printf("#3");
};
выход только:
Segmentation fault: 11
и, кажется, никогда не достигает основного, в чем причина?
На отпечатках отсутствует символ конца строки («\ n»). Segfault происходит до того, как вы выводите символ конца строки, и поэтому ничего не печатается. Пытаться
printf("#1\n");
РЕДАКТИРОВАТЬ:
Что касается того, почему происходит segfault, get («Cat») возвращает нулевой указатель, потому что вы не вызвали add («Cat»). Ошибка происходит из-за попытки вызова newObject для нулевого указателя.
Других решений пока нет …