2017-07-15 271 views
-1

我是新来的C++,我试图通过解决对黑客等级的挑战来发展我的技能。虚拟函数C++黑客等级挑战

这是我工作的 https://www.hackerrank.com/challenges/virtual-functions

挑战

我对挑战的解决方案是

class Person { 
protected: 
    int age; 
    string name; 

public: 
    virtual void getdata() { 
    } 
    virtual void putdata() { 
    }  
}; 

class Student: public Person{ 
protected: 
    int marks[6]; 
    int sum = 0; 
    static int cur_id2; 

public: 
    void getdata() { 
     cin >> name >> age; 

     for(int i = 0; i < 6; i++) { 
      cin >> marks[i] ; 
      sum = sum + marks[i]; 
     } 
    }  
    void putdata() { 
     cout << name <<" "<< age<<" " << sum <<" "<< cur_id2 << endl; 
    } 
    Student() { 
     cur_id2++; 
    } 
}; 

int Student::cur_id2 = 0; 

class Professor: public Person { 
protected: 
    int publications; 
    static int cur_id1; 

public: 
    void getdata() { 
     cin >> name >> age >> publications; 
    } 
    void putdata() { 
     cout << name <<" "<< age <<" "<< publications<<" " << cur_id1 << endl; 
    } 

    Professor() { 
     cur_id1++; 
    } 
}; 

int Professor::cur_id1 = 0; 

我得到这些结果:

Your Output 

Walter 56 99 2 
Jesse 18 403 2 
Pinkman 22 135 2 
White 58 87 2 

Expected Output 

Walter 56 99 1 
Jesse 18 403 1 
Pinkman 22 135 2 
White 58 87 2 

我觉得跟ID的问题在主函数中它总是获取所有对象的数据,然后才打印它,这意味着id变量将始终得到创建最后一个对象后的最后一个值,所以我认为这种方式是没有意义的,我需要另一种方法来为每个新的类实例分配一个id并保存在某个地方,以便在调用putdata函数时使用它。我想使用一个数组来保存所有的ID,但我不认为这是解决这个问题的正确方法,请帮助我。 谢谢

编辑:

谢谢你的答案帮助我解决我只是修改小段代码

protected: 
    int publications; 
    static int next_id1; 

    int cur_id1; 




    Professor(){ 

     cur_id1=++next_id1; 
    } 

};int Professor::next_id1=0; 

而且在学生类相同的挑战。

+1

你明白什么'静态'意味着一个类中的变量? –

回答

2

您似乎想要为每个Student和每个Professor分配一个唯一的ID值。要做到这一点,你需要两个变量:

  1. 类变量static int next_id;它记录下一个ID来使用。

  2. 成员变量int id;根据next_id为每个对象分配一个值。

我建议你阅读一下static在这方面的含义。

+0

谢谢,它真的有助于我理解静态变量,但我没有想过使用两个变量而不是一个变量。 – Iman

+0

@Iman这里的关键是要认识到有两块数据需要跟踪:1.下一个ID,它由类的所有实例共享,以及2.特定对象的ID,它属于每个目的。很高兴我能帮上忙。祝你好运,学习更多的编码! –

2

看起来您需要花一些时间阅读静态数据成员(例如here)。实际上,如果一个类的成员被声明为static,那么你的程序中存在该成员的一个值 - 该类的所有实例共享相同的static成员,并且可以使用(myClassInstance.StaticMember)和没有实例(MyClass::StaticMember )。

所以想想你可以如何与非静态成员一起使用它来解决你的问题。

class Professor : public Person { 
public: 
    Professor() : Person(), publications(0), cur_id(++key) { 
    } 
    virtual void getdata() { 
     std::cin >> name >> age >> publications; 
    } 
    virtual void putdata() { 
     std::cout << name << ' ' << age << ' ' << publications 
        << ' ' << cur_id << std::endl; 
    } 
private: 
    int publications; 
    int cur_id; 
    static int key; 
}; 
int Professor::key = 0; 

在我的例子,我用了一个static类变量来跟踪实例的数量:

+0

这就是我正在寻找的。我应该考虑使用静态变量的非静态变量。谢谢它有帮助。 – Iman

0

我通过以下方式(只显示了Professor类)解决了这一难题。这个变量对于所有实例都是相同的,所以当一个实例改变它时,另一个会看到改变。 cur_id是在构造函数中初始化的成员变量,不会被其他实例更改。

+0

谢谢你真的有帮助,我只是用同样的想法来解决挑战。 – Iman

0

这个简短的程序应该显示静态成员变量在类中的行为。

#include <vector> 
#include <string> 
#include <iostream> 
#include <iomanip> 
#include <map> 
#include <fstream> 

class Person { 
protected: 
    // sbcp = static base class Person 
    static unsigned sbcPID_; 
    const unsigned myID_ { sbcPID_ }; 

    std::string name_; 
    unsigned age_; 

public: 
    Person() { ++sbcPID_; } 
    Person(const std::string& name, unsigned age) : 
     name_(name), age_(age) { 
     ++sbcPID_; 
    } 

    static unsigned getBaseStaticID() { return sbcPID_; } 
    virtual unsigned getMyID() const { return this->myID_; } 

    std::string getName() const { return name_; } 
    unsigned getAge() const { return age_; } 

    virtual void getdata() { std::cout << "Person::getDataCalled\n"; /* code */ } 
    virtual void putdata() { std::cout << "Person::putDataCalled\n"; /* code */ } 
}; 

class Student : public Person { 
private: 
    // sdcS = static derived class Student 
    static unsigned sdcSID_; 
    const unsigned myID_ { sdcSID_ }; 

    int marks[6] {}; 
    int sum { 0 }; 

public: 
    Student() : Person() { ++sdcSID_; } 
    Student(const std::string& name, unsigned age) : 
     Person(name, age) { 
     ++sdcSID_; 
    } 


    static unsigned getDerivedStaticID() { return sdcSID_; } 
    virtual unsigned getMyID() const override { return this->myID_; } 

    virtual void getData() { std::cout << "Student::getDataCalled\n"; /* code */ } 
    virtual void putData() { std::cout << "Student::putDataCalled\n"; /* code */ } 
}; 

class Professor : public Person { 
private: 
    // sdcP = static derived class Proffesor 
    static unsigned sdcPID_; 
    const unsigned myID_ { sdcPID_ }; 

    int publications_; 

public: 
    Professor() : Person() { ++sdcPID_; } 
    Professor(const std::string& name, unsigned age) : 
     Person(name, age) { 
     ++sdcPID_; 
    } 

    static unsigned getDerivedStaticID() { return sdcPID_; } 
    virtual unsigned getMyID() const override { return this->myID_; } 

    virtual void getData() { std::cout << "Professor::getDataCalled\n"; /* code */ } 
    virtual void putData() { std::cout << "Professor::putDataCalled\n"; /* code */ } 
}; 

unsigned Person::sbcPID_ = 0; 
unsigned Student::sdcSID_ = 0; 
unsigned Professor::sdcPID_ = 0; 

int main() { 
    std::vector<Professor*> professors; 
    std::vector<Student*> students; 

    std::multimap<unsigned, Person*> allCampusMembers; 

    // Populate a staff of 5 professors; 
    std::vector<std::string> professorsNames { "D. Hall", "T. Roland", "S. McKinney", "A. Wesker", "J. Krispen" }; 
    std::vector<unsigned> professorAges { 39, 58, 27, 69, 42 }; 

    for (unsigned n = 0; n < 5; n++) { 
     professors.emplace_back(new Professor(professorsNames[n], professorAges[n])); 
     // Also add to our map 
     allCampusMembers.emplace(std::make_pair(professors[n]->getMyID(), dynamic_cast<Person*>(professors[n]))); 
    } 

    // Do the Same for 10 students 
    std::vector<std::string> studentNames { "M. Asbury", "D. Brighton", "L. Caldwell", "R. Griscom", "B. Koloski", 
              "J. Martin", "V. Ottaman", "A. Peterson", "S. Richards", "A. Samuels" }; 
    std::vector<unsigned> studentAges { 22, 21, 19, 20, 23, 
             26, 28, 32, 19, 21 }; 

    for (unsigned n = 0; n < 10; n++) { 
     students.emplace_back(new Student(studentNames[n], studentAges[n])); 
     // Also add to our map 
     allCampusMembers.emplace(std::make_pair(students[n]->getMyID(), dynamic_cast<Person*>(students[n]))); 
    } 

    // Also log to a text file: 
    std::fstream out("Log.txt", std::ios::out | std::ios::trunc); 

    // Use The Map To Go Through And Print Out The (Person ID), (Private ID), Name & Age. 
    std::multimap<unsigned, Person*>::iterator it = allCampusMembers.begin(); 

    for (; it != allCampusMembers.end(); ++it) { 
     out << "BaseID: " << it->second->getBaseStaticID() << " " 
      << "DerivedID: " << it->second->getMyID() << "\n" 
      << "Name: " << it->second->getName() << " " 
      << "Age: " << it->second->getAge() << "\n\n"; 

     std::cout << "BaseID: " << it->second->getBaseStaticID() << " " 
      << "DerivedID: " << it->second->getMyID() << "\n" 
      << "Name: " << it->second->getName() << " " 
      << "Age: " << it->second->getAge() << "\n\n"; 
    } 
    std::cout << std::endl; 

    // Clear Out Our Memory 
    allCampusMembers.clear(); 
    for (unsigned n = 0; n < professors.size(); n++) { 
     delete professors[n]; 
     professors[n] = nullptr;  
    } 
    professors.clear(); 

    for (unsigned n = 0; n < students.size(); n++) { 
     delete students[n]; 
     students[n] = nullptr; 
    } 
    students.clear(); 

    professorsNames.clear(); 
    professorAges.clear(); 
    studentNames.clear(); 
    studentAges.clear(); 

    std::cout << "\nPress any key and enter to quit." << std::endl; 
    char c; 
    std::cin >> c; 

    return 0; 
} 

如果按原样运行此简短程序;你应该得到这样的输出:

BaseID: 15 DerivedID: 0 
Name: D. Hall Age: 39 

BaseID: 15 DerivedID: 0 
Name: M. Asbury Age: 22 

BaseID: 15 DerivedID: 1 
Name: T. Roland Age: 58 

BaseID: 15 DerivedID: 1 
Name: D. Brighton Age: 21 

BaseID: 15 DerivedID: 2 
Name: S. McKinney Age: 27 

BaseID: 15 DerivedID: 2 
Name: L. Caldwell Age: 19 

BaseID: 15 DerivedID: 3 
Name: A. Wesker Age: 69 

BaseID: 15 DerivedID: 3 
Name: R. Griscom Age: 20 

BaseID: 15 DerivedID: 4 
Name: J. Krispen Age: 42 

BaseID: 15 DerivedID: 4 
Name: B. Koloski Age: 23 

BaseID: 15 DerivedID: 5 
Name: J. Martin Age: 26 

BaseID: 15 DerivedID: 6 
Name: V. Ottaman Age: 28 

BaseID: 15 DerivedID: 7 
Name: A. Peterson Age: 32 

BaseID: 15 DerivedID: 8 
Name: S. Richards Age: 19 

BaseID: 15 DerivedID: 9 
Name: A. Samuels Age: 21 

由于这会显示该静态成员变量使用更多作为其中const用于值唯一ID的引用计数。