将迭代器解除引用指针

时间:2015-10-15 04:57:48

标签: c++ pointers iterator

我有一个使用迭代器打印对象的程序。指向每个对象的指针存储在向量中。当我尝试通过解除引用迭代器来打印这些对象时,它只是打印内存位置。我相信它是因为我有更多的间接层由于指针,但当我再次取消引用时,我得到一个我无法追踪的段错误。有谁能找到问题?

int main(int argc, const char * argv[]){
    ObjectFactory* objFact = readInput();
    for (ObjectFactory::const_iterator p = objFact->begin(); p!=objFact->end(); ++p){
        std::cout << *p << " ";
    }

    return 0;
}

ObjectFactory* readInput(){
    std::vector<MyObject*> myObjects;
    ObjectFactory* objFact = ObjectFactory::get_inst();
    std::string input;
    int years_passed;
    std::cin >> years_passed;
    std::cin >> input;
    int age = 0;
    float diameter = 0;
    while (std::cin){
            try{
                    if (input == "int"){
                            int value;
                            if (std::cin >> value){
                                    if (value > 0){
                                            age = value;
                                            std::cin >> input;
                                    }
                                    else{
                                            std::cin >> input;
                                            throw negativeNumber("integer", value);
                                    }
                            }
                            else{
                                    std::cin.clear();
                                    std::cin >> input;
                                    throw missingValue("int", input);
                            }
                    }
                    else if (input == "float"){
                            float value;
                            if (std::cin >> value){
                                    if (value > 0){
                                            diameter = value;
                                            std::cin >> input;
                                    }
                                    else{
                                            std::cin >> input;
                                            throw negativeNumber("float", value);
                                    }
                            }
                            else{
                                    std::cin.clear();
                                    std::cin >> input;
                                    throw missingValue("float", input);
                            }
                    }
                    else if (input == "string"){
                            std::string value;
                            std::cin >> value;
                            if (diameter == 0 || age == 0){
                                    std::cin >> input;
                                    throw incompleteObject(value);
                            }
                            try{
                                    objFact->new_object(value, diameter, age);
                            }
                            catch (invalidAge ex){
                                    ex.printMessage();
                            }
                            std::cin >> input;
                    }
                    else{
                            std::string tempInput = input;
                            std::cin >> input;
                            throw unrecognizedType(tempInput);
                    }
            }
            catch (unrecognizedType ex){
                    ex.printMessage();
            }
            catch (incompleteObject ex){
                    ex.printMessage();
            }
            catch (negativeNumber ex){
                    ex.printMessage();
            }
            catch (missingValue ex){
                    ex.printMessage();
            }
    }
    return objFact;
}

class ObjectFactory {
public:
    static ObjectFactory* get_inst();
    MyObject*  new_object(std::string name,  float diameter, int age);
    void time_passed(int year);
    typedef std::vector<MyObject*>::const_iterator const_iterator;
    const_iterator begin() const{return objects.begin();}
    const_iterator end() const{return objects.end();}
protected:
    ObjectFactory(){}
private:
    static ObjectFactory* _instance;
    std::vector<MyObject*> objects;
};

ObjectFactory* ObjectFactory::_instance=0;
ObjectFactory* ObjectFactory::get_inst(){
    if (_instance ==0) {_instance = new ObjectFactory;}
    return _instance;
}
//Create the correct object type based of the name 
MyObject*  ObjectFactory::new_object(std::string name,  float diameter, int age){
    if (toupper(name.at(0)) == 'C'){
        objects.push_back((MyObject*)new Car(name, diameter, age));
        return objects.at(objects.size()-1);
    }
    if (toupper(name.at(0)) == 'T'){
        objects.push_back((MyObject*)new Tiger(name, diameter, age));
        return objects.at(objects.size()-1);
    }
    objects.push_back((MyObject*)new Human(name, diameter, age));
    return objects.at(objects.size()-1);
}

void ObjectFactory::time_passed(int year){
for (int i =  0; i < objects.size();i++){
    objects[i]->year_passed(year);
    if (objects[i]->get_age()>objects[i]->get_max_age()){
        delete objects[i];
    }
}
}
//Prints output for objecs of MyObject type
std::ostream& operator << (std::ostream& out, MyObject& obj)
{
    out << "(" <<obj.get_type_name() << "," << obj.get_name() << "," << obj.get_diameter() << "," << obj.get_age() << ","<< obj.get_speed() << ")";
}

ObjectFactory* ObjectFactory::_instance=0;
ObjectFactory* ObjectFactory::get_inst(){
if (_instance ==0) {_instance = new ObjectFactory;}
return _instance;
}
//Create the correct object type based of the name 
MyObject*  ObjectFactory::new_object(std::string name,  float diameter, int age){
    if (toupper(name.at(0)) == 'C'){
        objects.push_back((MyObject*)new Car(name, diameter, age));
        return objects.at(objects.size()-1);
    }
    if (toupper(name.at(0)) == 'T'){
        objects.push_back((MyObject*)new Tiger(name, diameter, age));
        return objects.at(objects.size()-1);
    }
    objects.push_back((MyObject*)new Human(name, diameter, age));
    return objects.at(objects.size()-1);
}

void ObjectFactory::time_passed(int year){
for (int i =  0; i < objects.size();i++){
    objects[i]->year_passed(year);
    if (objects[i]->get_age()>objects[i]->get_max_age()){
        delete objects[i];
    }
}
}
//Prints output for objecs of MyObject type
std::ostream& operator << (std::ostream& out, MyObject& obj)
{
    out << "(" <<obj.get_type_name() << "," << obj.get_name() << "," << obj.get_diameter() << "," << obj.get_age() << ","<< obj.get_speed() << ")";
}

我没有包含MyObject或其子类的代码或我正在使用的错误结构,因为它似乎不相关,但如果您需要它,请告诉我。

1 个答案:

答案 0 :(得分:1)

问题很可能是由于

中缺少return语句引起的
std::ostream& operator << (std::ostream& out, MyObject& obj)
{
   out << "(" <<obj.get_type_name() << "," << obj.get_name() << "," << obj.get_diameter() << "," << obj.get_age() << ","<< obj.get_speed() << ")";
}

如果您使用以下内容,肯定会导致未定义的行为:

std::cout << *(*p) << " ";

添加return声明。

另外,我会将obj更改为MyObject const&

std::ostream& operator << (std::ostream& out, MyObject const& obj)
{
   out << "(" <<obj.get_type_name() << "," << obj.get_name() << "," << obj.get_diameter() << "," << obj.get_age() << ","<< obj.get_speed() << ")";
   return out;
}