Implementing an Abstract Class - c++

I am a C++ noob and I have a noob question.
I have an abstract tree class definition in a header file. I know it is abstract because it contains virtual methods. It looks like so:
//AbsTree.h
class AbsTree {
public:
AbsTree();
virtual ~AbsTree() =0;
virtual void accept(Visitor &visitor) const = 0;
virtual void execute(Env &ctxt) const throw (InappropriateFunction);
};
class Operation: public AbsTree{
public:
Operation(char oper);
virtual ~Operation();
virtual void accept (Visitor &visitor) const;
char getOperator() const;
private:
char operator;
};
I have come up with the following implementation of this AbsTree:
AbsTree.cpp
#include "AbsTree.h"
AbsTree::AbsTree() {}
AbsTree::~AbsTree() {}
AbsTree::accept(Visitor &visitor) const{}
AbsTree::execute(Env &ctxt) const {}
Operation::Operation(char oper): operator(oper) {}
Operation::~Operation(){}
Operation::accept(Visitor &visitor) const{}
char Operation::getOperator() {
return operator;
}
So I try to compile the .cpp via:
g++ AbsTree.cpp -o AbsTree
and I get
AbsTree.cpp:3:1: error: 'AbsTree' does not name a type
AbsTree.cpp:4:1: error: 'AbsTree' does not name a type
AbsTree.cpp:5:1: error: 'AbsTree' does not name a type
AbsTree.cpp:6:1: error: 'AbsTree' does not name a type
AbsTree.cpp:8:1: error: 'Operation' does not name a type
AbsTree.cpp:9:1: error: 'Operation' does not name a type
AbsTree.cpp:10:1: error: 'Operation' does not name a type
AbsTree.cpp:11:6: error: 'Operation' has not been declared
AbsTree.cpp: In function 'char getOperator()':
AbsTree.cpp:12:9: error: 'operator' was not declared in this scope
Please expose me for the C++ noob that I am.

Here's a compilable/runnable version of your code (runnable at ideone here)
struct Visitor { };
struct Env { };
struct InappropriateFunction { };
class AbsTree {
public:
AbsTree();
virtual ~AbsTree() =0;
virtual void accept(Visitor &visitor) const = 0;
virtual void execute(Env &ctxt) const throw (InappropriateFunction);
};
class Operation: public AbsTree{
public:
Operation(char oper);
virtual ~Operation();
virtual void accept (Visitor &visitor) const;
char getOperator() const;
private:
char operator_;
};
AbsTree::AbsTree() {}
AbsTree::~AbsTree() {}
void AbsTree::accept(Visitor &visitor) const{}
void AbsTree::execute(Env &ctxt) const throw (InappropriateFunction) {}
Operation::Operation(char oper): operator_(oper) {}
Operation::~Operation(){}
void Operation::accept(Visitor &visitor) const{}
char Operation::getOperator() const {
return operator_;
}
int main()
{
Operation o('x');
Visitor my_visitor;
o.accept(my_visitor);
o.getOperator();
}
Basically, you've got to take more care to make sure the functions you define match your declarations - that includes const and throw specifications and return type. Further, operator is a reserved keyword and you can not use it to name your own variables.
Separately, exception specifications are deprecated... best to leave them out as they never proved useful. (C++11 has a noexcept keyword that's occasionally useful if you want to make it clear that a function can be used in code making exception guarantees - might get a little extra optimisation too, but if an exception is raised in/under the function your program will call std::terminate).

AbsTree is an abstract class, like you said. This means that you need to create a derived class in order to provider an implementation.
// ConcreteTree.h
#include "AbsTree.h"
class ConcreteTree : public AbsTree {
public:
ConcreteTree();
virtual ~ConcreteTree();
virtual void accept(Visitor &visitor) const;
virtual void execute(Env &ctxt) const throw (InappropriateFunction);
}
Then:
// ConcreteTree.cpp
#include "ConcreteTree.h"
ConcreteTree::ConcreteTree() {}
ConcreteTree::~ConcreteTree() {}
ConcreteTree::accept(Visitor &visitor) const{}
ConcreteTree::execute(Env &ctxt) const {}

Related

C++ error: object of abstract class type is not allowed

Having trouble with inheritance. I do not know what is wrong with the script..
in main
int main(){
Repository repo("dogs.txt");
FileAdoptionList* a = new CSVDoglist{}; / here is the error
Controller ctrl(repo, dogValidator{}, a);
UI ui(ctrl);
ui.startUI();
delete a;
}
CSVDoglist.h
class CSVDoglist : public FileAdoptionList
{
public:
void writeToFile();
void displayAdoptionlist() const;
};
FileAdoptionList.h
class FileAdoptionList : public AdoptionList
{
protected:
std::string filename;
public:
FileAdoptionList();
virtual ~FileAdoptionList() {}
void setFilename(const std::string& filename);
virtual void writeToFile() = 0;
virtual void displayAdoptionList() const = 0;
};
AdoptionList.h
class AdoptionList
{
protected:
std::vector<Dog> storage;
public:
AdoptionList();
// Adds a dog to the playlist.
void add(const Dog& dog);
// Checks if the adoptionlist is empty.
bool isEmpty();
virtual ~AdoptionList() {}
};
ERRORS:
object of abstract class type "CSVDoglist" is not allowed:
'CSVDoglist': cannot instantiate abstract class Adoptig Dogs
I have read more topics about this problem but I didn't found the solution.
Can someone help me? Thanks
It seems you have a typo.
A function named displayAdoptionlist (contains small l) is declared in CSVDoglist, but the pure virtual function displayAdoptionList (contains large L) isn't overrided in CSVDoglist.

Passing a pointer type as a template parameter

The following code
#include <iostream>
template<typename T>
class Abstract
{
public:
virtual ~Abstract()
{}
virtual void func(const T &param) const = 0;
};
class Concrete : public Abstract<int*>
{
public:
virtual void func(const int *&param) const override // watch out!
{}
};
int main()
{
Concrete c;
}
produces the following compile error at the line marked with the comment:
error C3668: 'Concrete::func' : method with override specifier 'override' did not override any base class methods
If I remove the override, this error will be shown:
error C2259: 'Concrete' : cannot instantiate abstract class
How to derive from Abstract<int*>?
Declare Concrete like this:
class Concrete : public Abstract<int*>
{
public:
virtual void func(int * const &param) const override
{}
};
The question is: Which part of the parameter of Abstract<int*>::f() is const?
The answer: Since T is const and T in Abstract<int*> is a pointer (to an int), it is the pointer that is const - not the int.
You want this:
virtual void func(int * const &param) const override // watch out!

Overriding virtual member function containing constant

How can I override a virtual member function of the following type:
virtual AnimalId func(int index) const
where AnimalId is a typedef unsigned int
I tried several ways but either ending up by an error that I don't give output or that I don't have an overrider at all. I saw on some website that maybe I need to use static const in order to do this, but I don't know how.
In order to override method of signature
virtual AnimalId func(int index) const
declared in base class Base, you have to define function with same signature in derived class:
class Derived : public Base {
public:
virtual AnimalId func(int index) const
{
return 43; // I am using 43 because I think this is
// so much underestimated in favor of 42
}
//...
};
Or you can type override kryword to be more explicit:
class Derived : public Base {
public:
virtual AnimalId func(int index) const override
{
return 43 & 45;
}
//...
};
Did you mean something like: (Note, you have to remove override if you compile for C++03)
typedef unsigned int AnimalId;
class Base
{
public:
virtual ~Base() {}
virtual AnimalId func(int index) const { return 0; }
};
class Derived : public Base
{
public:
AnimalId func(int index) const override { return 42; }
};

Why does implementation of abstract class not see overloaded pure virtual function?

Given the following code example, why is the overloaded AbstractBaseClass::DoAThing( const char* ) not visible as an inherited method in the SomeEndClass that implements the overloaded pure abstract DoAThing( const char* const* ) method?
class AbstractBaseClass
{
public:
virtual void DoAThing( const char* withThis ) {}
virtual void DoAThing( const char* const* withThat ) = 0;
AbstractBaseClass() {}
virtual ~AbstractBaseClass() {}
};
class SomeMiddlewareClass : public AbstractBaseClass
{
public:
void ThisIsCool() {}
SomeMiddlewareClass() {}
virtual ~SomeMiddlewareClass() {}
};
class SomeEndClass : public SomeMiddlewareClass
{
public:
void DoAThing( const char* const* withThat ) {}
SomeEndClass() {}
virtual ~SomeEndClass() {}
};
void SomeFunction()
{
SomeEndClass* myClass = new SomeEndClass();
myClass->DoAThing( "withThis" );
((SomeMiddlewareClass*)myClass)->DoAThing( "withThisToo" );
delete myClass;
}
The compiler (and indexer) produce the following error on the myClass->DoAThing( "withThis" ); line while the ((SomeMiddlewareClass*)myClass)->DoAThing( "withThisToo" ); line is accepted.
Invalid arguments ' Candidates are: void DoAThing(const char * const *)
no matching function for call to ‘SomeEndClass::DoAThing(const char [9])’
Shouldn't the SomeEndClass inherit the AbstractBaseClass::DoAThing( const char* ) implementation? What am I doing wrong?
Your SomeEndClass::DoAThing() function not only overrides the function inherited from the base class, but also hides the other overloads of that function in the base class.
You could add a using declaration to your SomeEndClass class:
using SomeMiddlewareClass::DoAThing;
Therefore:
class SomeEndClass : public SomeMiddlewareClass
{
public:
using SomeMiddlewareClass::DoAThing;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void DoAThing( const char* const* withThat ) {}
SomeEndClass() {}
virtual ~SomeEndClass() {}
};
With this fix, you can see your program compiling in this live example.
In your base class DoAThing is not just virtual, but overloaded.
The function in the derived class overrides one of those overloads and hides the other.
You're then trying to call the other, which is hidden.
You can make the hidden function visible in the derived class with a using declaration:
using Base::DoAThing;
...but whether you should is a separate (more complex) question.

g++ won't compile my complex template instantiation

I use MinGW latest version to compile the following code. I get the folowing message
y:/bbom/source/om0/basic/test.cpp: In static member function 'static void somecl
ass::init(class_object*)':
y:/bbom/source/om0/basic/test.cpp:68:50: error: no matching function for call to
'class_object::add_method(void (&)(object*, arch&))'
y:/bbom/source/om0/basic/test.cpp:68:50: note: candidate is:
y:/bbom/source/om0/basic/test.cpp:27:54: note: template<class p_function> void c
lass_object::add_method(typename p_function::funcion_type)
make.exe: *** [y:/bbom/bin/om0/basic/test.a] Error 1
Here is my code undressed from every thing not needed for this question
#include <exception>
class exception : public std::exception
{
public:
exception() {}
exception(const exception &);
~exception() throw() {}
virtual const char *what() const throw();
};
typedef unsigned id, version;
class class_object;
class object
{
public:
virtual ~object() {}
void *get_method(id);
class_object *get_class_object();
};
class class_object : public object
{
public:
template <class p_function>
void add_method(typename p_function::funcion_type p)
{add_method2((void *)p, p_function::function_id);}
void add_method2(void *, id);
};
template <typename p_func, id p_id>
class function
{
public:
typedef p_func function_type;
enum {function_id = p_id, };
function(object *p) {m_func = (p_func)p->get_method(p_id);}
p_func m_func;
};
class iface : public object
{
public:
iface(object *p) : m_object(p) {}
static void init(class_object *) {}
object *m_object;
};
class arch;
class archivable : public iface
{
public:
typedef void (*archive_func_type)(object *, arch &);
typedef function<archive_func_type, 0x5afeb287> archive_type;
archivable(object *);
archive_type archive;
};
class someclass : public object
{
public:
static void archive(object *, arch &)
{
}
static void init(class_object *p)
{
p->add_method<archivable::archive_type>(archive);
// the compiler says this call cannot be matched to
// add_method declared in class 'class_object'
}
};
What is wrong with my call to the template method in class_object::add_method<...>()
It appears you mistyped function_type as funcion_type on line 27 of test.cpp.
Typo. funcion_type should be function_type.