Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于函数参数选择派生类_C++ - Fatal编程技术网

C++ 基于函数参数选择派生类

C++ 基于函数参数选择派生类,c++,C++,我有以下课程: 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 getWidt

我有以下课程:

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();

}

现在回答我的问题。我的主要观点如下:

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;部分可能是问题的根源,因为范围不同。但不管怎样,有没有办法我该怎么做?我省略了代码中枯燥和不相关的部分。

Base应该有一个虚拟析构函数,并且您想要重写的每个函数都应该声明为虚拟的。此外,您的主要功能需要进行一些修改:

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将尝试从标准输入读取。您的注释表明您正在加载一个文件,因此假设该文件是std::ifstream实例cin.getlinefile,10将尝试调用一个不存在的函数std::istream::getlinestd::istream&,int。getline执行您在此处似乎想要执行的操作。此外,即使您试图读取标准输入,也应该是std::getlinestd::cin,s,而不是cin.getlinefile,10

接下来,下一个问题是内存泄漏。通过1在声明b时初始化它,2在泄漏内存之前正确地删除它,可以很容易地修复这些问题。对于初始化的b,null检查并不是完全必要的,因为delete无论如何都会检查null,但我在那里写了它们来说明一点:您应该正确地管理内存

接下来,if-else-if条件有可能不执行任何操作,也就是说,b在更坏的情况下是未初始化的,或者在最好的情况下是NULL。如果您不想对非s/h输入执行任何操作,这很好,但是您必须执行以下操作,无论如何您都应该这样做


最后,可能导致崩溃的问题是在尝试使用b之前没有检查b是否有效:b->toString;。如果b无效或为null,则调用未定义的行为。你的程序可能会崩溃,打电话给你的祖母,或者给总统点比萨饼。。。所有选项都是有效的选项,其中没有一个是您真正想要做的。

您确定其中一个if语句正在执行吗?如果它们都不执行,b就没有被初始化,这可能是你的问题。这甚至可以编译吗?!由于从未删除过b,因此也在泄漏内存,如果此操作运行一段时间,最终会出现内存不足异常。您的基类需要一个虚拟析构函数。如果您计划重写它,则还应标记为String virtual。我认为这不应成为一个错误answer@khajvah想详细说明吗?这不是他的问题的答案。您已经提供了一些有用的信息,但这并不是为什么它不起作用的答案?或者我该怎么做?。这将编译并运行,但很可能不会像OP预期的那样工作,因为您只是防止了它失败。公平地说,用OP提供的信息回答是不可能的,但是…他的问题的答案仍然是变化:主要是,在他尝试调用b->toString之前的null检查,当他使用null或未初始化的指针调用它时,这可能会导致程序崩溃。事实上,有一部分不会像他写的那样编译,我在编辑中提到过。@khajvah在我详细介绍的时候看到了我的编辑。
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;
}