Why is class abstract although it shouldn't be? - c++

I've been looking at this code for few hours and I can't find why I can't instantiate class. So I have interfaces:
class ICloneable {
public:
virtual ICloneable* clone() const = 0;
virtual ~ICloneable() = 0 {}
};
class IPrintable
{
protected:
virtual void print(std::ostream&) const = 0;
public:
virtual ~IPrintable() = 0;
friend std::ostream& operator<<(std::ostream, const IPrintable&);
};
std::ostream& operator<<(std::ostream os, const IPrintable& other) {
other.print(os);
return os;
}
class IComparable {
protected:
virtual bool is_greater(const IComparable& other) const = 0;
virtual bool is_equal(const IComparable& other) const = 0;
public:
virtual ~IComparable() = 0;
virtual bool operator>(const IComparable& other) const {
return is_greater(other);
}
virtual bool operator<(const IComparable& other) const {
return !(is_greater(other) || is_equal(other));
}
virtual bool operator==(const IComparable& other) const {
return is_equal(other);
}
virtual bool operator!=(const IComparable& other) const {
return !(is_equal(other));
}
};
And I have two classes that inherit these interfaces:
class I2DShape : public IComparable, public IPrintable {
public:
virtual void print(std::ostream& os) const override final {
os << "Circumference: " << this->circumference();
}
virtual bool is_greater(const I2DShape& other) const final {
return this->circumference() > other.circumference();
}
virtual bool is_equal(const I2DShape& other) const final {
return this->circumference() == other.circumference();
}
virtual double circumference() const = 0;
virtual ~I2DShape();
};
class IPositionable : public IPrintable, public IComparable {
public:
virtual void print(std::ostream& os) const override final {
}
virtual bool is_greater(const IPositionable& other) const final {
distance_from_origin() > other.distance_from_origin();
}
virtual bool is_equal(const IPositionable& other) const final {
distance_from_origin() == other.distance_from_origin();
}
virtual double distance_from_origin() const {
return sqrt(pow(center().get_x(), 2) + pow(center().get_y(), 2));
}
virtual Point center() const = 0;
virtual ~IPositionable();
};
And in the final these two classes are inherited by one which represents shape:
class Shape2D : public IPositionable, public I2DShape, public ICloneable {
protected:
int num_of_points;
Point* points;
public:
Shape2D() : num_of_points(0), points(nullptr) {}
Shape2D(int num) : num_of_points(num), points(new Point[num]) {}
Shape2D(const Shape2D& other) : num_of_points(other.num_of_points) {
points = new Point[num_of_points];
for (int i = 0; i < num_of_points; i++) {
points[i] = other.points[i];
}
}
Shape2D& operator=(const I2DShape& other) {
}
virtual Shape2D* clone() const override = 0;
virtual ~Shape2D() {
if(points)
delete[] points;
}
};
When I derive Square from Shape2D and make function for cloning, I get error that it's abstract class:
class Square : public Shape2D {
private:
double side;
public:
Square() {}
Square(double s, Point center) : side(s), Shape2D(1) { points[0] = center;}
virtual Point center() const override{
return points[0];
}
virtual double circumference() const override {
return 4 * side;
}
virtual Square* clone() const override final {
return new Square(*this); //error on this line
}
};
Error: object of abstract class type "Square" is not allowed

Since in interfaces you declared destructors with = 0 you are forcing explicit implementation of it in sub-classes which can be instantiated.
There are two ways to fix it.
Make interface classes in standard way with default destructors (no = 0), using {} or = default.
Add explicit destructor for Square
Note that pure virtual destructor with implementation is treated by gcc and clang as an error.
Related SO questions:
Why do we need a pure virtual destructor in C++?
Pure virtual function with implementation

The error was as #HolyBlackCat stated in the comments, with function is_greater and is_equal because they have different parameters when overriden. Simple fix to this was to remove = 0 from those two functions in IComparable so they weren't pure.

Related

Virtual Equal Function between templated classes (C++)

This question is a follow up on Here. The goal was to implement a virtual equal operator between non templated classes. In this question, I am asking for the same goal for a templated class.
#define EQUAL_FOR_BASE(derived) virtual bool equal(const derived& eq) const { return false; };
#define EQUAL_FOR_DERIVED(this_derived) bool equal(const Equalable& equalable) const { return equalable.equal(*this_derived); };
class RandomClass; //This is for clarification purposes, not used.
class DerivedTemplateType_One;
class DerivedTemplateType_Two;
class Equalable
{
public:
Equalable() = default;
virtual ~Equalable() = default;
virtual bool operator==(const Equalable& eq) { return this->equal(eq); };
EQUAL_FOR_BASE(RandomClass);
EQUAL_FOR_BASE(DerivedTemplateType_One);
EQUAL_FOR_BASE(DerivedTemplateType_Two);
virtual bool equal(const Equalable& eq) const = 0;
};
class RandomClass : public Equalable
{
public:
RandomClass() = default;
~RandomClass() = default;
EQUAL_FOR_DERIVED(this);
virtual bool equal(const RandomClass& rc) const { return m_double == rc.m_double; };
double m_double;
};
class TemplateType : public Equalable //Still pure virtual due to equal in Equalable.
{
public:
TemplateType() = default;
virtual ~TemplateType() = default;
int m_string;
};
class DerivedTemplateType_One : public TemplateType
{
public:
EQUAL_FOR_DERIVED(this);
virtual bool equal(const DerivedTemplateType_One& one) const { return m_int == one.m_int; };
int m_int;
};
class DerivedTemplateType_Two : public TemplateType
{
public:
EQUAL_FOR_DERIVED(this);
virtual bool equal(const DerivedTemplateType_Two& two) const { return m_size == two.m_size; };
std::size_t m_size;
};
template<typename T>
class Target : Equalable
{
public:
T m_t;
};
Q1: I want to limit the template typename T above to be a derived class of TemplateType (derived from Equalable) e.g. Can be DerivedTemplateType_One/Two (Of course there will be Three, Four..)? Isn't there static_assert or some metaprogramming to check this at compile time or would:
template<TemplateType DerivedTypeOneOrTwo>
class Target : public Equalable
{
public:
DerivedTypeOneOrTwo m_t;
};
Work?
Q2: How can I implement the equal operator as I did for RandomClass please?
Q3: I am asking about Q1 in order to limit template types possible so that Q2 is possible, can I generalize Q1: Limit template typename T to classes inheriting from Equalable (instead of TemplateType ) and still do Q2?
Sorry this is getting a bit complicated but there is no easy way :) Thanks very much!!
Ps: I am making everything public to save space, please ignore.
I ended using CRTP if anyone is interested (Please let me know if I am doing something wrong I missed)
template<class Derived>
class Equalable
{
public:
using derived_type = Derived;
bool operator==(const Derived& derived) const { return this->equal(derived); };
bool operator!=(const Derived& derived) const { return !(*this == derived); }
private:
virtual bool equal(const Derived& derived) const = 0;
};
class B : public Equalable<B>
{
public:
B(double d) : m_example(d) {};
private:
virtual bool equal(const B& derived) const override { return derived.m_example == m_example; };
double m_example;
};
class A : public Equalable<A>
{
public:
A(std::string d) : m_example(d) {};
private:
virtual bool equal(const A& derived) const override { return derived.m_example == m_example; };
std::string m_example;
};
Now we can compare element of same type:
int main()
{
A a("string");
B b(1);
A aa("other_string");
B bb(11);
std::cout << (a == aa) << std::endl; //Ok
std::cout << (b == bb) << std::endl; //Ok
std::cout << (a == b) << std::endl; //Wrong, not supported.
};
I tried doing this:
template<class A, class B>
static bool equal(const Equalable<A>& a, const Equalable<B>& b)
{
if (!std::is_same<A, B>::value)
return false;
return a == b;
};
But didn't compile, so I just used equality between same types.
To limit template (As of Question Q1) there a standard check:
static_assert(std::is_base_of<Base, Derived>::value, "Only from Base");
Hope you have better suggestions, I still don't like this :) Thanks everyone!

Virtual Equal Function on C++

I am trying to do something like:
class A
{
public:
A() = default;
~A() = default;
public:
bool operator==(const A& a)
{
return this->equal(a);
};
private:
virtual bool equal(const A& other) const = 0;
};
class B : public A
{
public:
B() = default;
~B() = default;
private:
virtual bool equal(const A& other) const override
{
const B* b = dynamic_cast<const B*>(&other);
if (!b)
return false;
return m_example == b->m_example;
}
private:
double m_example; //This is just an example data I don't need specific solution for double :)
};
Goal: Only equality possible is between classes of same type = B.
Is that ok?
Is there a standard solution to have a virtual equal operator?
I will be inherting from A a lot (4/8 classes), how can I do this in a clean way, the check if the pointer is null looks very ugly.
Could you please help me?
It's a matter of opinion whether dynamic casts are ugly, or not. It's an endless debate, but it doesn't matter here. That's because dynamic casts are not needed here. This can be done, cleanly, using inheritance:
class B; // Forward declaration.
class A {
// Same as above
private:
virtual bool equal(const A& other) const = 0;
virtual bool equal(const B& other) const { return false; }
};
// ... B class:
bool equal(const A& other) const override
{
return other.equal(*this);
}
bool equal(const B &other) const override
{
return m_example == other.m_example;
}

Overloading == and != operators in C++ with polymorphism

Here is the thing. I have one base class and 4 child classes.
class Base{
public:
virtual int getType() const = 0;
};
class Type1 : public Base{
public:
virtual int getType() const {
return 1;
};
};
class Type2 : public Base{
public:
virtual int getType() const {
return 2;
};
};
class Type3 : public Base{
public:
virtual int getType() const {
return 3;
};
};
class Type4 : public Base{
public:
virtual int getType() const {
return 4;
};
};
I need to overload the == and != operators which do the same thing for all child classes, just retrieve the type values and compare them. So I would naturally implement the operator in the Base class with references to Base as both operands but when I do that, my IDE starts screaming when I use the operators on child views, that it cannot compare structs.
So the question is. Is there a way I can implement the operators just once without having to specify them for each combination of child classes ?
Thanks!
I do not have any problem with this operator:
bool operator==(Base const& x, Base const& y)
{
return x.getType() == y.getType();
}
unless with an accessibility issue: Your getType function is private. If you do not provide any access modifier with classes, all members, variables and functions, are implicitly private.
So you either need a friend declaration or make the getType function public.
class Base {
public:
virtual int getType() const = 0;
bool operator ==(const Base &b) const {
return getType() == b.getType();
}
};
class Type1 : public Base {
public:
virtual int getType() const {
cout << "Type1.getType()" << endl;
return 1;
};
};
class Type2 : public Base {
public:
virtual int getType() const {
cout << "Type2.getType()" << endl;
return 2;
};
};
Usage:
Base *t1 = new Type1(), *t2 = new Type2();
bool res1 = *t1 == *t1; // true, calls Type1.getType() twice
bool res2 = *t1 == *t2; // false, calls Type1.getType() and Type2.getType()
Yes, you can do it in your Base class. There will be no error for doing this.
class Base{
public:
virtual int getType() const = 0;
bool operator==(const Base& rhs) const{
return getType() == rhs.getType();
}
bool operator!=(const Base& rhs) const{
return !(*this == rhs);
}
};

Virtual public base class method not visible in ancestor [duplicate]

This question already has answers here:
Why does an overridden function in the derived class hide other overloads of the base class?
(4 answers)
Closed 7 years ago.
When compiling the following code :
class Base {
public:
Base(){}
virtual ~Base(){}
virtual bool equals(const Base* rhs) const { return false;}
};
class DerivedA : public Base {
public:
DerivedA() : Base(), val(0) {}
virtual ~DerivedA() {}
virtual bool equals(const DerivedA* rhs) const { return this->val == rhs->val;}
int val;
};
class DerivedB : public Base {
public:
DerivedB() : Base(), val(0) {}
virtual ~DerivedB() {}
virtual bool equals(const DerivedB* rhs) const { return this->val == rhs->val;}
int val;
};
int main() {
const DerivedA a;
const DerivedB b;
std::cout << a.equals(&b);
}
I get:
../main.cpp:104:26: error: no matching function for call to ‘DerivedA::equals(const DerivedB*) const’
std::cout << a.equals(&b);
^
../main.cpp:104:26: note: candidate is:
../main.cpp:88:15: note: virtual bool DerivedA::equals(const DerivedA*) const
virtual bool equals(const DerivedA* rhs) const { return this->val == rhs->val;}
^
../main.cpp:88:15: note: no known conversion for argument 1 from ‘const DerivedB*’ to ‘const DerivedA*’
But why doesn't it use the base class virtual bool equals(const Base* rhs) const?
bool DerivedA::equals(const DerivedA* rhs) const
is not an override of
bool Base::equals(const Base* rhs) const
but an other overload (as you may notice with override) which hides the base method.
If you just want to 'unhide' base method, you may add
using Base::equals;
into your derived class.
But to really solve your issue, you have to use multiple dispatch.

c++ invoke base classes' virtual operator== with multiple inheritance

Given the following excerpts:
class Interface {
public:
virtual bool operator==(const Interface &other) const = 0;
virtual void print(ostream& sout) const = 0;
};
class A : virtual public Interface {
public:
virtual bool operator==(const Interface &other)const;
virtual void print(ostream& sout)const;
protected:
short m_foo;
};
class B : virtual public Interface {
public:
virtual bool operator==(const Interface &other)const;
virtual void print(ostream& sout) const;
protected:
short m_bar;
};
class C: public A, public B {
public:
virtual bool operator==(const Interface &other) const;
virtual void print(ostream& sout) const;
};
In C.cpp I'm trying to implement operator==:
bool C::operator==(const Interface &other) const {
try {
// This works, but it's duplicating code from A.cpp and B.cpp
const C& otherC = dynamic_cast<const C&>(other);
return (m_foo == otherC.m_foo && m_bar == otherC.m_bar);
// This doesn't work -- it calls C::operator== instead of
// A::operator== and B::operator== (infinite recursion).
/*
return (dynamic_cast<const A&>(*this) ==
dynamic_cast<const A&>(other) &&
dynamic_cast<const B&>(*this) ==
dynamic_cast<const B&>(other));
*/
} catch (bad_cast e) {
return false;
}
}
I can get it to work for the output method, but I don't know how to do
something equivalent when overriding operators:
void C::print(ostream& sout) const {
A::print(sout);
sout << " ";
B::print(sout);
}
Is there a way to call the base classes' virtual operators instead of doing
something like adding a virtual equals() method and just having operator== call
that?
(Note: this code is based off of a small part of a homework assignment in case
that's relevant.)
You need to explicitly name the operator you want to use.
Replace:
return (dynamic_cast<const A&>(*this) ==
dynamic_cast<const A&>(other) &&
dynamic_cast<const B&>(*this) ==
dynamic_cast<const B&>(other));
With Edit: corrected
return (A::operator==( other ) &&
B::operator==( other ));
return A::operator==(other) && B::operator==(other);
The two base classes should handle any type error in other, so you don't need to do anything about that here.
EDIT: rewrote code to use explicit call.