-1

我有这些课程:

class Base
{
  private:
    string name;
  public:
    void setName(string n);
    string getName();
    void toString();
}

以及由此派生的两个类:

class DerivedA : public Base
{
  private:
    int width;
  public:
    void setWidth(int w);
    int getWidth();

}

class DerivedB : public Base
{
  private:
    int height;
  public:
    void setHeight(int h);
    int getHeight();
}

现在我的问题。我的主要看起来像这样:

int main()
{        
  Base* b;    
  string line;
  ... file loading ...

  while(...)
  {
    s = cin.getline(file,10);        
    if(s == "w")
    {
      b = new DerivedA();        
    }
    else if(s == "h")
    {
      b = new DerivedB();
    }
    while(...)
    {
      b->toString();
    }
  }

return 0;
}

这总是会终止我的应用程序。我发现该b->toString();部分可能是问题的根源,因为范围不同。但无论如何,有没有办法我可以做到这一点?(我省略了无聊且不相关的代码部分。)

4

1 回答 1

2

Base应该有一个虚拟析构函数,并且应该声明您打算覆盖的每个函数virtual。此外,您的main函数需要一些修改:

int main()
{        
    Base* b = nullptr; // initialize your pointer    
    string line;
    // ... file loading ...

    while(std::getline(file, line)) // this should be your while loop for your file parsing
    {
        //s = cin.getline(file,10); // why???  you appear to be trying to pass your ifstream object into cin's istream::getline method ... this won't even compile!

        // I'm assuming s is a std::string, and you pull it out of the line variable at some point ...
        if(s == "w")
        {
           if (b != nullptr) // properly free your memory
           {
               delete b;
               b = nullptr;
           }
           b = new DerivedA();        
        }
        else if(s == "h")
        {
           if (b != nullptr) // properly free your memory
           {
               delete b;
               b = nullptr;
           }
            b = new DerivedB();
        }

        while(...)
        {
            if (b != nullptr) // make sure b is valid!
            {
                b->toString();
            }
        }
    }

    return 0;
}

这总是会终止我的应用程序。我发现 b->toString(); 由于范围不同,部分可能是问题的根源。但无论如何,有没有办法我可以做到这一点?

首先,您发布的内容(可能)甚至无法编译。 cin.getline将尝试从标准输入中读取。您的评论表明您正在加载一个文件,因此(假设这file是一个std::ifstream实例,cin.getline(file, 10)正在尝试调用一个std::istream::getline(std::istream&, int)不存在的函数。 std::getline执行您想要在此处执行的操作。此外,即使您尝试从标准读取输入,应该是std::getline(std::cin, s),不是cin.getline(file, 10)

继续前进,下一个区域是您的内存泄漏。这些很容易通过 1)b在声明时进行初始化,以及 2)delete在泄漏内存之前正确地修复它。空值检查不是完全必要的(使用初始化的b),因为无论如何delete都会检查NULL,但我把它们写在那里是为了说明一点:你应该正确地管理你的内存!

接下来,您的 if-else if 条件有可能不做任何事情(也就是说,b在更糟的情况下或NULL充其量是未初始化)。如果您不想为非“s”/“h”输入做任何事情,那很好,但是您必须执行以下项目(无论如何您都应该这样做)。

最后,可能导致您崩溃的问题是b在尝试使用它之前未检查是否有效: b->toString();. 如果b无效或为空,则您正在调用未定义的行为。你的程序可能会崩溃,打电话给你的祖母,或者为总统点一份披萨……所有这些都是有效的选择,而这些都不是你真正打算做的。

于 2013-10-30T21:04:42.860 回答