Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@Panchatcharam
Last active March 29, 2017 07:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Panchatcharam/d5e7f5a5f0242b4c0487996c280086fe to your computer and use it in GitHub Desktop.
Save Panchatcharam/d5e7f5a5f0242b4c0487996c280086fe to your computer and use it in GitHub Desktop.
#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;
}
@Panchatcharam
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment