2017-07-15 256 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的引用計數。