Last active
March 29, 2017 07:01
-
-
Save Panchatcharam/d5e7f5a5f0242b4c0487996c280086fe to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <memory> | |
#include <numeric> | |
#include <exception> | |
using namespace std; | |
class base | |
{ | |
public: | |
base(); | |
virtual void getdata() = 0; | |
virtual void putdata() = 0; | |
virtual ~base() = default; | |
}; | |
template<typename T> | |
class Person : public base | |
{ | |
public: | |
Person(string Name="", int Age=0) : name(Name), age(Age) | |
{ | |
++cur_id; | |
} | |
virtual ~Person() {} | |
protected: | |
string name; | |
int age; | |
static int cur_id; | |
}; | |
template<typename T> int Person<T>::cur_id = 0; | |
class Professor : public Person<Professor> | |
{ | |
public: | |
Professor(string Name="", int Age=0, int Publications=0); | |
~Professor() {} | |
void getdata() override; | |
void putdata() override; | |
protected: | |
bool IsValidInput(); | |
private: | |
int publications; | |
}; | |
Professor::Professor(string Name, int Age, int Publications) try : Person(Name,Age), publications(Publications) | |
{ | |
} | |
// Catch constructor that fails | |
catch(std::exception & e) | |
{ | |
std::cout<<"\n Exception - "<<e.what()<<std::endl; | |
exit(1); | |
} | |
bool Professor::IsValidInput() | |
{ | |
if (name.empty() || (name.length() > 100)) | |
{ | |
return false; | |
} | |
if ( age <= 0 || age > 80 ) | |
{ | |
return false; | |
} | |
if ( publications <= 0 || publications > 1000) | |
{ | |
return false; | |
} | |
return true; | |
} | |
void Professor::getdata() | |
{ | |
cout<< "Enter Name age publications" << endl; | |
cin >> name >> age >> publications; | |
if (!IsValidInput()) | |
{ | |
throw std::invalid_argument("wrong arguments"); | |
} | |
} | |
void Professor::putdata() | |
{ | |
cout << name << " " << age << " " << publications << " " << cur_id << endl; | |
} | |
class Student : public Person<Student> | |
{ | |
public: | |
Student(string Name="", int Age=0, const vector<int> & Marks = {}); | |
~Student() {} | |
void getdata() override; | |
void putdata() override; | |
protected: | |
bool IsValidInput(); | |
private: | |
vector<int> marks; | |
static const int TOTAL_MARKS = 5; | |
}; | |
Student::Student(string Name, int Age, const vector<int> & Marks) try : Person(Name,Age), marks(Marks) | |
{ | |
} | |
// Catch constructor that fails | |
catch(std::exception & e) | |
{ | |
std::cout<<"\n Exception - "<<e.what()<<std::endl; | |
exit(1); | |
} | |
void Student::getdata() | |
{ | |
int mark = 0; | |
cout<< "Enter Name age marks(5)" << endl; | |
cin >> name >> age; | |
for (size_t idx = 0; idx < TOTAL_MARKS; ++idx) | |
{ | |
cin >> mark; | |
marks.push_back(mark); | |
} | |
if (!IsValidInput()) | |
{ | |
throw std::invalid_argument("wrong arguments"); | |
} | |
} | |
void Student::putdata() | |
{ | |
cout << name << " " << age << " " << std::accumulate(marks.begin(),marks.end(),0) << " " << cur_id << endl; | |
} | |
bool Student::IsValidInput() | |
{ | |
if (name.empty() || (name.length() > 100)) | |
{ | |
return false; | |
} | |
if ( age <= 0 || age > 80 ) | |
{ | |
return false; | |
} | |
for (size_t idx = 0; idx < marks.size(); ++idx) | |
{ | |
if ( marks[idx] < 0 || marks[idx] > 100 ) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
int main() | |
{ | |
int totalObj = 0, type = 0; | |
std::cout<< "Enter total obj : "; | |
std::cin >> totalObj; | |
std::vector<std::unique_ptr<base>> person; | |
for (int idx = 0; idx < totalObj; ++idx) { | |
std::cout<< "Enter obj type (1 or 2) : "; | |
std::cin >> type; | |
switch(type) { | |
case 1: { | |
auto temp = std::make_unique<Professor>(); | |
temp->getdata(); | |
person.emplace_back(std::move(temp)); | |
} | |
break; | |
case 2: { | |
auto temp = std::make_unique<Student>(); | |
temp->getdata(); | |
person.emplace_back(std::move(temp)); | |
} | |
break; | |
default: | |
break; | |
} | |
} | |
for (auto&& p : person) { | |
p->putdata(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The sample explains how to use CRTP design pattern to have specific static data defined for each instance of a derived class, where the static data declared in the base class.