虚拟函数 C++ 黑客排名挑战

Virtual Functions C++ Hacker rank challenge

我是 c++ 的新手,我试图通过解决 Hacker Rank 上的挑战来发展我的技能。

这是我正在应对的挑战 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 的问题是在 main 函数中它总是在打印之前获取所有对象的数据,这意味着 id 变量总是在创建最后一个对象后获得最后一个值所以我认为这个方法没有意义 我需要另一种方法来为 class 的每个新实例分配一个 id 并将其保存在某个地方以便在调用 putdata 函数时使用它。我想过使用数组来保留所有 ID,但我认为这不是解决此问题的正确方法,请帮助我。 谢谢

编辑:

谢谢你所有的回答帮助我解决了挑战我只是修改了一小段代码

 protected: 
   int publications;
   static int next_id1; 

  int cur_id1; 




  Professor(){

        cur_id1=++next_id1;  
    }

};int Professor::next_id1=0;

学生也一样class。

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

  1. 一个 class 变量 static int next_id; 跟踪下一个要使用的 ID。

  2. 成员变量int id;,根据next_id.

  3. 为每个对象赋值

我建议您阅读 static 在这种情况下的含义。

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

访问它们

所以考虑一下如何将它与非静态成员一起使用来解决您的问题。

我通过以下方式解决了这个挑战(仅显示 Professor class):

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 class 变量来跟踪实例数。此变量对于所有实例都是相同的,因此当一个实例更改它时,另一个实例将看到更改。 cur_id是一个成员变量,在构造函数中初始化,不会被其他实例更改。

这个短程序应该展示 类.

中静态成员变量的行为
#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 值。

这是完成此程序的另一种更简单的方法......

class Person
{
protected:
  int age;
  string name;
public:
      virtual void getdata(){};
      virtual void putdata(){};
};
class Professor : public Person
{
    int publication;
    static int id1;
      public:
       void getdata()
       {
           cin>>name;
           cin>>age;
           cin>>publication;
       }
       void putdata()
       {
          cout<<name<<" "<<age<<" "<<publication<<" "<<id1<<endl;
          id1++;
       }
};
int Professor::id1=1;
class Student : public Person
{
    int marks[6];
     static int id2;
  public:
      int sum=0;
   void getdata()
   {
       cin>>name;
       cin>>age;
       for(int i=0;i<=5;i++)
       {
          cin>>marks[i];
          sum=sum+marks[i];
       }
   }
   void putdata()
   {
      cout<<name<<" "<<age<<" "<<sum<<" "<<id2<<endl;
      id2++;
   }
};
int Student::id2=1;

我是这样解决的:

class Person
{
    public :

    string name;
    int age;
    virtual void getdata() =0;
    virtual void putdata() =0;

};

class Professor : public Person 
{
    private :
    static int id1;
    int publications;
    public :
    void getdata()
    {
        cin>>name>>age>>publications;
    }
    void putdata()
    {
        cout<<name<< " "<<age<<" "<<publications<<" "<<id1<<endl;
        id1++;
    }
};

int Professor::id1=1;
class Student : public Person
{
    private :
    static int id2;
    int marks[6];
    int sum=0;

    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<<" "<<id2<<endl;
        id2++;
    }
};
int Student::id2=1;