【问题标题】:C++ return value reference of std::map [closed]std::map 的 C++ 返回值引用 [关闭]
【发布时间】:2017-08-28 13:03:04
【问题描述】:

我有一个:std::map<string,Star> galaxy,我希望下面的 find_star() 方法返回对此映射中值的引用。我没有收到任何编译错误,但它不会返回任何参考。

Star& Galaxy::find_star(const string& name){
    try{
    return galaxy.at(name);
    }
    catch(out_of_range a){
        cerr<<"Error: "<<a.what()<<" Key not found!"<<endl;
    }
}

调试器在传递“return”行时收到未知信号。

main.cpp
int main(){
    Galaxy g("stars-newline-leer.txt");
    g.print();
    Star s;
    s=g.find_star("Caph");//Working correctly until here 
return 0;
}

Star.cpp

Star::Star() {
}

Star::Star(const Star& obj) {
    this->id=obj.id;
    this->ms=obj.ms;
    this->prim_id=obj.prim_id;
    this->bez=obj.bez;
    this->sb=obj.sb;
    this->x=obj.x;
    this->y=obj.y;
    this->z=obj.z;


}

Star::~Star() {
}

istream& operator>>(istream& is, Star& obj) {
    string str = "";
    int i = 0;

    getline(is, str); //Id einlesen
    obj.id = stoi(str);

    getline(is, str); //Bezeichnung einlesen
    obj.bez = str;

    getline(is, str); //x-Koordinate
    obj.x = stod(str);

    getline(is, str); //y-Koordinate
    obj.y = stod(str);

    getline(is, str); //z-Koordinate
    obj.z = stod(str);

    getline(is, str); //Sternenbild
    obj.sb = str;

    getline(is, str); //Mehrfachsternsys
    obj.ms = stoi(str);

    getline(is, str); //Primärstern-Id
    obj.prim_id = stoi(str);


    return is;

}



ostream& operator<<(ostream& os, Star& obj) {
    os << "ID: " << obj.id << endl;
    os << "Name: " << obj.bez << endl;
    os << "Koordinaten: " << obj.x;
    os << ", " << obj.y;
    os << ", " << obj.z << endl;
    os << "Sternenbild: " << obj.sb << endl;
    os << "System-Id: " << obj.ms << endl;
    os << "Pimärstern: " << obj.prim_id << endl;
    return os;
}

void Star::print()const {


    cout << "ID: " << id << endl;
    cout << "Name: " << bez << endl;
    cout << "Koordinaten: " <<fixed<< x;
    cout << ", " <<fixed<< y;
    cout << ", " <<fixed<< z << endl;
    cout << "Sternenbild: " << sb << endl;
    cout << "System-Id: " << ms << endl;
    cout << "Pimärstern: " << prim_id << endl;
}

对不起,我是 Stackoverflow 的新手,我不习惯这个。为什么我需要添加非代码来提交我的编辑。我想我只是说了所有关于它的内容。

【问题讨论】:

  • 看起来应该可以了。你能提供一个minimal reproducible example 吗?
  • 那么如果一个异常被捕获,你希望你的函数返回什么?
  • 不相关,但您应该通过引用捕获异常对象。否则,由于可能的对象切片,您会丢失信息。 out_of_range 没有子类。但最好保持一致。
  • 啊谢谢忘记了
  • 我现在编辑了我的问题。一切正常:我的print() 方法,构造函数,直到我调用find_star() 方法@NathanOliver

标签: c++ reference return stdmap


【解决方案1】:

@CoryKramer 评论说,您的 find_star 函数存在设计问题。

当您收到out_of_range 异常时,您不会返回Star 引用,此时您可以抛出另一个异常,但这会使您的代码变得不必要的复杂...

我的建议是您只需在 main 函数中使用 map::find

int main(){

    Galaxy g("stars-newline-leer.txt");
    g.print();
    Star s;
    map<string,Star>::iterator it = s.find("Caph");
    if(it != m.end())
    {
      //element found;
      s = it->second;
    }
    else
    {
      cout<<"Error: "<< it->first << " Key not found!" << endl;
    }
    return 0;
}

编辑

如果您想使用您的自定义查找函数来抛出(或重新抛出异常),您可以按如下方式进行:

Star& Galaxy::find_star(const string& name){
    try{
      return galaxy.at(name);
    }
    catch(const std::out_of_range& a){
      cerr<<"Error: "<<a.what()<<" Key not found!"<<endl;
      throw; //an internal catch block forwards the exception to its external level
    }
}

然后你需要在main 块中再次捕获异常。

int main(){
  Galaxy g("stars-newline-leer.txt");
  g.print();
  Star s;
  try{
    s=g.find_star("Caph");
  }
  catch(const std::exception& e){
    //Do something here
  }
  return 0;
}

【讨论】:

  • 我知道异常问题。但我的任务是实现一个类方法,它接受一个字符串并返回对象的引用,如果它存在于容器中,如果找不到则抛出异常。
  • @PaulFi,已编辑以满足您的评论!
  • 啊,好吧,这似乎是一个很好的解决方案。是否可以有两个 catch 块接受不同类型的异常?因为我已经为另一种异常类型添加了另一个 catch 块。 @Rama
  • @PaulFi 是的,请参阅en.cppreference.com/w/cpp/language/try_catch 中的说明
猜你喜欢
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-29
  • 1970-01-01
  • 2023-03-27
相关资源
最近更新 更多