I am trying to use a pure virtual class as a parameter in a program, however, i get a compile error:
Error 1 error C2259: 'Person': cannot instantiate abstract class
I guess the error im getting is because A) its not possible to instantiate an abstract class and B) i can't use an abstract class as i would use an interface in C#
The C# program below illustrates what im trying to do in the C++ program. How can i write generic code using abstract classes in C++? if im forced to use a more specialized version of Person e.g. Employee, the code is not really generic. Do i have to use templates?
#include<iostream>
#include<vector>
class Person {
public:
virtual std::string getName() = 0;
virtual void setName(std::string name) = 0;
virtual std::string toString() = 0;
private:
std::string name;
};
class Employee : public Person {
public:
std::string getName() {
return this->name;
}
void setName(std::string name) {
this->name = name;
}
std::string toString() {
return "name:" + this->name;
}
private:
std::string name;
};
class Repository {
public:
void add(Person& p) {
this->repo.push_back(p);
}
private:
std::vector<Person> repo;
};
int main(int argc, char* argv[])
{
Repository repo;
Employee emp1;
emp1.setName("John Doe");
repo.add(emp1);
return 0;
}
interface IPerson
{
string GetName();
void SetName(string name);
string ToString();
}
class Employee : IPerson
{
private string _name;
public string GetName() {
return this._name;
}
public void SetName(string name) {
this._name = name;
}
public override string ToString() {
return "name: " + this._name;
}
}
class Repository
{
private List<IPerson> _repo;
public Repository() {
this._repo = new List<IPerson>();
}
public void Add(IPerson p) {
this._repo.Add(p);
}
}
class Program
{
static void Main(string[] args)
{
Repository repo = new Repository();
Employee emp1 = new Employee();
emp1.SetName("John Doe");
repo.Add(emp1);
}
}
The problem is that Repository is storing Person objects, and this class cannot be instantiated*. This is because std::vector<Person> holds Person values.
You can store pointers to Person instead, but you have to ensure they live at least as long as the Repository instance. For example,
/// class repository does not own Persons it holds
class Repository {
public:
void add(Person& p) {
this->repo.push_back(&p);
}
private:
std::vector<Person*> repo;
};
* Note that in general it is possible to construct a base class object from a derived type one. The base object would be constructed from the base sub-object of the derived one (see What is object slicing?). In your case, this fails because the base type is abstract.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With