HackerRank - Virtual Function Practice This is just simple code to practice the use of virtual functions from a practice challenge in HackerRank. Could you give me some advice about the best practices and style?

This is just a simple exercise from HackerRank 

#include &lt;string&gt;
#include &lt;array&gt;
#include &lt;numeric&gt;
#include &lt;iostream&gt;
#include &lt;algorithm&gt;

class Person {
    protected:
    std::string name;
    int age;
    public:
    virtual void getdata() = 0;
    virtual void putdata() const = 0;
};
class Student final : public Person {  
    static inline int id_count = 0;
    std::array&lt;int,6&gt; marks;
    int cur_id;
    public:
    Student(){
        cur_id = ++Student::id_count;
    }
    void getdata() override {
        std::cin &gt;&gt; this-&gt;name;
        std::cin &gt;&gt; this-&gt;age;
        for (auto &amp;mark : marks) {
            std::cin &gt;&gt; mark;
        }
    }
    void putdata() const override{
        std::cout &lt;&lt; name &lt;&lt; " " &lt;&lt; age &lt;&lt; " " &lt;&lt; std::accumulate(marks.begin(), marks.end(), 0) &lt;&lt; " " &lt;&lt; cur_id &lt;&lt; std::endl;
    }
};

class Professor final : public Person {
    static inline int id_count = 0;
    int publications;
    int cur_id;

    public:
    Professor(){
        cur_id = ++Professor::id_count;
    }
    void getdata() override {
        std::cin &gt;&gt; this-&gt;name;
        std::cin &gt;&gt; this-&gt;age;
        std::cin &gt;&gt; this-&gt;publications;
    }
    void putdata() const override {
        std::cout &lt;&lt; name &lt;&lt; " " &lt;&lt; age &lt;&lt; " " &lt;&lt; publications &lt;&lt; " " &lt;&lt; cur_id &lt;&lt; endl;
    }
};


Code provided by the question (cannot be edited):


 int main(){
    int n, val;
    std::cin&gt;&gt;n; //The number of objects that is going to be created.
    Person *per[n];

    for(int i = 0;i &lt; n;i++){

        std::cin&gt;&gt;val;
        if(val == 1){
            // If val is 1 current object is of type Professor
            per[i] = new Professor;

        }
        else per[i] = new Student; // Else the current object is of type Student

        per[i]-&gt;getdata(); // Get the data from the user.

    }

    for(int i=0;i&lt;n;i++)
        per[i]-&gt;putdata(); // Print the required output for each object.

    return 0;

}
Be consistent.
You use a blank line to separate classes Student and Professor: Person and Studentdeserve no less. (Same goes for change in accessibility; alternatives to a blank line include (less) indent.)   
Don't write, never present uncommented code.
Use all machine/tool support you can get: have a look at doxygen.
make classes (and functions) final when further derivation/overriding is bound to break something, only.
Think of derivation as extension or specialisation.
You declared common attributes for Person: try and do the same for behaviour, even if it is more cumbersome in C++ (&amp; influenced languages) than in Simula: There, a virtual function gets to call inner - with common code before&amp;after.
In C++, I know no better than starting Derived::f() with Base::f();.
In this example, getdata() &amp; putdata() shouldn't be pure virtual:
Person::getdata() should input name and age; Person::putdata() output them. We are stuck without a method to handle specialised output is complete imposing. One can define void putdata() const { std::cout &lt;&lt; toString() &lt;&lt; std::endl; } (with toString() facing the exact problem with cur_id "on the other side").
Avoid overly long lines.  

name + " " + std::to_string(age)
     + " " + std::accumulate(marks.begin(), marks.end(), 0)
     + " " + std::to_string(cur_id)


is easier to read and probably works just as well as a one-liner.


(While this review has been received exceedingly friendly,
the following code misses the mark correct contemporary C++ by a mile.
(Hopefully closing in with revisions (incorporating advice from Edward's answer);
Having "fun" with IDEone - don't hold your breath.))  

Shots from the hip:

/*! \brief Person sporting common attributes
 *         and get/putdata().
 *
 *  Attributes include name, age, and an in-subclass ID.
 *  getdata() reads from std::cin, starting with name&amp;age;
 *  putdata() writes a line to std::cout.
 */
class Person {
 protected:
    //    const int cur_id;
    std::string name;
    int age;
    /*! terse human readable representation.
    */
    virtual std::string toString() const {
        return name + " " + std::to_string(age);
    }
    ~Person(){}
 public:
    /*! read name&amp;age from std::cin.
     */
    virtual void getdata() {
        std::cin &gt;&gt; name &gt;&gt; age;
    }
    /*! putdata() writes a line to std::cout.
     */
    virtual void putdata(std::ostream &amp;out = std::cout) const {
        out &lt;&lt; toString() &lt;&lt; std::endl;
    }
};

/*! Student adds marks for subjects to the common attributes.
 */
class Student : public Person {
    const int cur_id;
//    static std::atomic&lt;int&gt; id_count(0);
    std::array&lt;int, 6&gt; marks;
 protected:
    std::string toString() const override {
        return Person::toString()
        + " " + std::to_string(
            std::accumulate(marks.begin(), marks.end(), 0))
        + " " + std::to_string(cur_id);
    }
 public:
    static int id_count;// = 0;
    Student() : cur_id(++id_count) {}
    /*! read as Person from std::cin; add marks.
     */
    void getdata() override {
        Person::getdata();
        for (auto &amp;mark : marks)
            std::cin &gt;&gt; mark;
    }
};

/*! Professor adds a publication count to the common attributes.
 */
class Professor final : public Person {
    const int cur_id;
//    static std::atomic&lt;int&gt; id_count(0);
    int publications;
 protected:
    std::string toString() const override {
        return Person::toString()
        + " " + std::to_string(publications)
        + " " + std::to_string(cur_id);
    }
 public:
    static int id_count;// = 0;
    Professor() : cur_id(++id_count) {}
    /*! read as Person from std::cin; add publications.
     */
    void getdata() override {
        Person::getdata();
        std::cin &gt;&gt; publications;
    }
};

int Student::id_count = 0;
int Professor::id_count = 0;