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

时间:2017-07-15 22:37:35

标签: c++ virtual-inheritance

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

编辑:

谢谢你所有的答案帮助我解决了我刚刚修改过的小段代码的挑战

 protected: 
   int publications;
   static int next_id1; 

  int cur_id1; 




  Professor(){

        cur_id1=++next_id1;  
    }

};int Professor::next_id1=0;

同样在学生班上。

6 个答案:

答案 0 :(得分:2)

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

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

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

  3. 我建议您阅读static在此背景下的含义。

答案 1 :(得分:2)

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

因此,请考虑如何与非静态成员一起使用它来解决您的问题。

答案 2 :(得分:0)

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

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

答案 3 :(得分: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值。

答案 4 :(得分:0)

这是完成此程序的另一种简便方法。

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;

答案 5 :(得分:0)

我这样解决了:

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;