Here is my example code which produces the error:
struct Impl
{
int data_size_;
int find(int var){return 0;}
int get(int rowid){return 0;}
};
class Container
{
public:
Container() {}
virtual ~Container() {}
virtual int get_size() = 0;
virtual int get(int rowid) = 0;
};
class SortedContainer : virtual public Container {
public:
virtual int find(int var) = 0;
};
class ContainerImpl : public Container
{
protected:
Impl impl_;
public:
int get_size() {return impl_.data_size_;}
int get(int rowid) {return impl_.get(rowid);}
};
class SortedContainerImpl
: public SortedContainer, public ContainerImpl
{
private:
typedef ContainerImpl Base;
public:
int find(int var){return Base::impl_.find(var);}
};
ContainerImpl ci;
SortedContainerImpl sci;
it seems "SortedContainerImpl" went wrong while "ContainerImpl" is fine.
g++ complains:
example_b.cpp:42:21: error: cannot declare variable ‘sci’ to be of abstract type ‘SortedContainerImpl’
example_b.cpp:32:7: note: because the following virtual functions are pure within ‘SortedContainerImpl’:
example_b.cpp:13:15: note: virtual int Container::get_size()
example_b.cpp:14:15: note: virtual int Container::get(int)
I inheret SortedContainerImpl from ContainerImpl in order to reuse get_size() and get(int)
I'm not familiar with c++, What's the nature of this problem and How can I fix it?
Thanks all.
In C++, once you have a pure virtual member function, your class becomes an abstract class and you cannot create any objects from it. Such a class is not meant to be instantiable by itself. It is meant to act as an Interface. One would derive from such an abstract class and provide implementations of all the pure virtual functions in the derived class.
Note that your class SortedContainerImpl derives from two classes SortedContainer and ContainerImpl. SortedContainer in turn derives from Container but it never implements the pure virtual functions.
Your SortedContainerImpl class has two separate Container base classes. One is virtual (via the SortedContainer class) and the other is non-virtual (via the ContainerImpl class).
SortedContainerImpl has concrete implementations of Container::get_size() and Container::get(int) for the base that comes in from ContainerImpl, but not for the virtual base that comes in via SortedContainer.
One way to fix the problem is to give concrete implementations in SortedContainerImpl:
class SortedContainerImpl
: public SortedContainer, public ContainerImpl
{
private:
typedef ContainerImpl Base;
public:
int find(int var){return Base::impl_.find(var);}
int get_size() {return ContainerImpl::get_size();}
int get(int rowid) {return ContainerImpl::get(rowid);}
};
Another way would be to make Container a virtual base class of ContainerImpl, so SortedContainerImpl would only get the one, virtual, base Container:
class ContainerImpl : virtual public Container
{
protected:
Impl impl_;
public:
int get_size() {return impl_.data_size_;}
int get(int rowid) {return impl_.get(rowid);}
};
Related
I have got myself into a strange issue now. Ill write a really simplified version of the same.
class Base
{
public:
virtual int func1()=0;
virtual int func2()=0;
protected:
int n;
};
class der1: public Base
{
// implements the virtual functions of the base and uses the protected data
// members of the base.
};
class der2: public Base
{
// implements the virtual functions of the base and uses the protected data
// members of the base.
}
Now the problem.... both der1 and der2 implements the virtual functions of base pretty much the same way. But some other classes (der3, der4) has their own implementations. But still need to inherit from base.
How do i refactor the code to remove the code duplication in an oop manner?
Here's one solution using an intermediate layer of another abstract base class:
class Base12 : public Base {
protected:
int commonFuncStuffA() {
// Commonly used stuff
}
int commonFuncStuffB() {
}
};
class der1: public Base12
{
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = somethingElse;
}
};
class der2: public Base12
{
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = commonFuncStuffB();
}
};
What I'd do for real production code design looks a bit different though.
Declare an interface for the pure virtual functions
struct IMyInterface {
virtual int func1() = 0;
virtual int func2() = 0;
virtual ~IMyInterface {}
};
Provide a abstract base class with the commonly used data members and functions
class BaseImpl : public IMyInterface {
protected:
int n;
int commonFuncStuffA() {
// Commonly used stuff
}
int commonFuncStuffB() {
// Commonly used stuff
}
};
Provide implementations of the interface in the finally derived classes
class der1: public BaseImpl {
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = somethingElse;
}
};
class der2: public BaseImpl {
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = commonFuncStuffB();
}
};
class der3: public IMyInterface {
public:
virtual int func1() {
// Some completely different implementation of the interface
}
virtual int func2() {
// Some completely different implementation of the interface
}
};
class der4: public IMyInterface {
public:
virtual int func1() {
// Some completely different implementation of the interface
}
virtual int func2() {
// Some completely different implementation of the interface
}
};
Option 1
You may consider using your most common implementation in the Base class. The main feature or drawback of this method is that the base class would no longer be abstract. If this is a problem, go to option 2.
Maybe you can even cope with differences in the derived classes by using the template method pattern to extract the differences in protected virtual functions invoked by the template method.
In anyway, for derived classes that need a completely different appoach, you'd just override the the Base class' method.
class Base
{
public:
virtual int func1();
virtual int func2()=0;
protected:
virtual void f1_specific_part1()=0;
virtual void f1_specific_part2()=0;
int n;
};
int Base::func1() { // common skeleton of the algorithm
...
f1_specific_part1();
...
f1_specific_part2();
...
}
class Der1: public Base
{
protected:
void f1_specific_part1() override; // Implements the specific variation
virtual void f1_specific_part2() override;
};
Option 2
You may consider to factorize the common code of the derived classes into a protected method of the Base class.
The override of the pure virtual function would then just call the base class protected common function (for der1 and der2) or just use their own implementation that is completely different (for der3 and der4).
class Base
{
public:
virtual int func1()=0;
virtual int func2()=0;
protected:
int common_part1_funct1(); // implements some common parts
int common_part2_funct1();
int n;
};
class Der1: public Base
{
...
int func1() override {
common_part1_funct1();
...
common_part2_funct1();
...
}
};
Option 3 ?
Important remark: My answer assumes that there are many commonalities between most of the derived classes. However if you have only a small subset of derived classes that share some commonalities, then the answer of Evg would be would be more appropriate.
The idea with Base12 is:
struct Base {
virtual int func1() = 0;
virtual int func2() = 0;
};
struct Base12 : Base {
protected:
int func12();
};
struct Der1: public Base12 {
virtual int func1() {
return func12();
virtual int func2() {
return func12();
};
struct Der2: public Base12 {
virtual int func1() {
return func12();
virtual int func2() {
return func12();
};
Consider the following code:
#include <stdio.h>
#include <iostream>
/// Header-file
class Base {
public:
virtual void do_something() const =0;
int GetAttrib () const {return constattribute_;};
static const int constattribute_;
};
typedef Base* Derived_Ptr; //<< adress derived classes by their base-class ptr; so no templates for Base
class DerivedA : public Base {
// static const int constattribute_; //<< change this static attribute for all DerivedA class instances and their derivatives
void do_something() const {};
};
class DerivedB : public Base {
// static const int constattribute_; //<< change this static attribute for all DerivedB class instances and their derivatives
void do_something() const {};
};
/// CC-file
using namespace std;
const int Base::constattribute_(0);
const int DerivedA::constattribute_(1); //<<error: no such variable 'constattribute' in class DerivedA
const int DerivedB::constattribute_(2); //<<error: no such variable 'constattribute' in class DerivedB
int main(void) {
Derived_Ptr derivedA = new DerivedA();
Derived_Ptr derivedB = new DerivedB();
cout << derivedA->GetAttrib() << derivedB->GetAttrib() <<endl;
return 0;
};
The intend being that i have some abstract interface (Base) which defines also a variable, which should be present for all derived classes, and is retrievable. All flavours of subclasses should be forced to/able to redefine their specific value for this variable, at best during class declaration (the values are known at the time the class is declared after all).
I want to achieve code, not altering the main()-program so that the output is '12' and not as of now (uncommenting current lines in the code) '00' (Doing so shadows the fields from base class).
I tried to look into the matter, and there are different paths for solutions, many of which however go contrary to my intuition:
1. Some follow the CRTP pattern, which is however impossible if I want to address my subclasses by their base-ptr in main.
2. Other solutions require to virtualize the 'GetAttrib()' function for every derived instance., which is cumbersome, and action of modifying the attribute is masked within a function definition.
3. A third possibility is to remove the static pattern and have the 'constattribute_' field as a regular member, which however forces me to drag it through all constructors as a parameter.
I am quite sure that there must be some smarter way to do this. Any hints are appreciated.
Using CRTP may get you what you want, assuming you don't have to access GetAttr() through Base* and can leave without constattribute_ in Base itself. Just follow the rule that every programming problem can be solved by entering another level of indirection, which I did below:
class Base {
public:
virtual void do_something() const = 0;
virtual ~Base() // should define it as you are using Base*
{
}
};
typedef Base* Derived_Ptr;
template<class T>
class BaseConstAttr : public Base
{
public:
int GetAttrib () const
{
return(constattribute_);
};
static const int constattribute_;
};
class DerivedA : public BaseConstAttr<DerivedA>
{
public:
void do_something() const
{
};
};
class DerivedB : public BaseConstAttr<DerivedB>
{
public:
void do_something() const
{
};
};
template<> const int BaseConstAttr<DerivedA>::constattribute_(1);
template<> const int BaseConstAttr<DerivedB>::constattribute_(2);
If you need GettAttr from top to bottom of the inheritance tree you can modify the above code a bit, but this will cost you making GetAttr virtual (but still one implementation only):
class Base {
public:
virtual void do_something() const = 0;
virtual int GetAttrib () const = 0;
virtual ~Base() // should define it as you are using Base*
{
}
};
typedef Base* Derived_Ptr;
template<class T>
class BaseConstAttr : public Base
{
public:
int GetAttrib () const
{
return(constattribute_);
};
static const int constattribute_;
};
class DerivedA : public BaseConstAttr<DerivedA>
{
public:
void do_something() const
{
};
};
class DerivedB : public BaseConstAttr<DerivedB>
{
public:
void do_something() const
{
};
};
template<> const int BaseConstAttr<DerivedA>::constattribute_(1);
template<> const int BaseConstAttr<DerivedB>::constattribute_(2);
Please note that I don't know how well (or bad) it will behave with deep inheritance tree (ie. when inheriting from DerivedA and/or DerivedB). In this case I would probably remove BaseConstAttr from inheritance tree right below Base and would try to inject it between most derived class and its predecessor or use multiple inheritance.
What you are requesting requires virtual dispatch somewhere, because you don't know the type of the object you are dealing with until runtime. The purpose of virtual dispatch is to solve exactly the problem you are facing.
The simplest solution is what you have given as number 2: make GetAttrib() virtual, and implement it on each derived class where you introduce a shadowing constattribute_.
static variable in base class is single instance hence it will be reflected same in derived class.
You can make same static member variable in derived class with specific different value you want. Now make getter member function of static variable in Base class as virtual and overload it in derived class which returns is static instance value.
I have update your code to work it, please check ..
#include <iostream>
using namespace std;
class Base {
public:
static const int constattribute_;
virtual void do_something() const =0;
virtual int GetAttrib () const {return constattribute_;};
};
typedef Base* Derived_Ptr; //<< adress derived classes by their base-class ptr; so no templates for Base
class DerivedA : public Base {
static const int constattribute_; //<< change this static attribute for all DerivedA class instances and their derivatives
void do_something() const {};
int GetAttrib () const {return constattribute_;};
};
class DerivedB : public Base {
static const int constattribute_; //<< change this static attribute for all DerivedB class instances and their derivatives
void do_something() const {};
int GetAttrib () const {return constattribute_;};
};
const int Base::constattribute_(0);
const int DerivedA::constattribute_(1); //<<error: no such variable 'constattribute' in class DerivedA
const int DerivedB::constattribute_(2); //<<error: no such variable 'constattribute' in class DerivedB
int main(void) {
Derived_Ptr derivedA = new DerivedA();
Derived_Ptr derivedB = new DerivedB();
cout << derivedA->GetAttrib() << derivedB->GetAttrib() <<endl;
return 0;
};
You should get desired output.
Note : Remember all member variables and func in derived class are private.
Please look at inheritance:
interface IArray
{
virtual unsigned __int8* GetAddress() const = 0;
virtual unsigned int GetItemCount() const = 0;
virtual unsigned int GetItemSize() const = 0;
};
template<class T>
class CustomArrayT : public IArray
{
public:
virtual unsigned __int8* GetAddress() const;
virtual unsigned int GetItemCount() const;
virtual unsigned int GetItemSize() const;
T& GetItem(unsigned int index);
};
interface IFloatArray : public CustomArrayT<float>
{
virtual IFloatArray* GetCompressedData() const = 0;
};
class ShannonFloatArray : public IFloatArray
{
public:
virtual IFloatArray* GetCompressedData() const;
};
class FourierFloatArray : public IFloatArray
{
public:
virtual IFloatArray* GetCompressedData() const;
};
class MickyMouseFloatArray : public IFloatArray
{
public:
virtual IFloatArray* GetCompressedData() const;
};
Main goal of the question is inheritance IFloatArray -> CustomArrayT: interface inherits some none abstract class. I do not want to support multiple inheritance. But I need all downtree classes has functionality of class CustomArrayT and implementing interface IFloatArray.
What pros and cons of such tree?
How could it be done by another way? Maybe some pattern?
I would do it like this:
template<class T>
class IArray {
public:
virtual int size() const=0;
virtual T map(int index) const=0;
};
All the pointers are just unnecessary.
One issue with your heirarchy is exactly what is the IArray interface for?
If you wished to pass any instantiated derived class as a reference or pointer to IArray you can't benefit from polymorphism as you would need to downcast before adding or retrieving any contained values. (Because IArray cannot define a getter or setter function without declaring the type to be got or set, and that type depends on which derived class was instantiated.)
Why can't the base class be templated? The "base" class should be CustomArray, and the "derived" classes could arguably be typedefs.
And why not use std::vector? (Possibly, for the practice.)
I want to make a class with a member function that takes a reference to another class, where both classes are derived from abstract classes. I get a compiler error that the class Container is abstract because it doesn't implement addElem().
class Ielem
{
public:
virtual void action() = 0;
};
class Elem: public Ielem
{
public:
void action() {};
void extra() {};
};
class Icontainer
{
public:
virtual void addElem(Ielem &elem) = 0;
};
class Container: public Icontainer
{
public:
void addElem(Elem &elem) { elem.extra(); };
};
int main(int argc, char* argv[])
{
Elem e;
Container c;
c.addElem(e);
return 0;
}
It seems like this ought to work, because any reference to an Elem is also a reference to an Ielem. It compiles if I make Container::addElem take a reference to an Ielem. But then Container::addElem() can't call Elem::extra() unless I use dynamic_cast, which isn't available on the embedded compiler I'm using, or a regular cast, which isn't type safe.
Suggestions?
It's the wrong way round: the base class Icontainer specifies that addElem can take any Ielem object as an argument, but in your derived class you accept only Elem. This is a "narrower" type, so the contract "I'll accept any Ielem you throw at me" specified in the base class is violated.
I think templates would be the solution here. You don't even need the base classes anymore. Something like this:
class Elem
{
public:
void action() {};
void extra() {};
};
template<typename ElemType>
class Container
{
public:
void addElem(ElemType &elem) { elem.extra(); };
};
int main(int argc, char* argv[])
{
Elem e;
Container<Elem> c;
c.addElem(e);
return 0;
}
As a bonus, you can now use Container with any type that has an extra() function, and it will just work.
The problem is simply that your virtual method doesn't have the same signature as the concrete method which is intended to overload it; so the compiler sees it as a different function entirely and complains because you haven't implemented void addElem(Ielem &elem). This is one solution, which you probably don't want--
class Icontainer
{
public:
virtual void addElem(Elem &elem) = 0; //Ielem -> Elem
};
It depends on all your other constraints but I think what I would do--and what seems to conform to general design guidelines, e.g. Sutter & Alexandreascu, would be to create an intermediate abstract class with the full interface--
class Melem: public Ielem
{
public:
// void action() {}; //Already have this form Ielem
void extra() = 0;
};
and then
class Icontainer
{
public:
virtual void addElem(Melem &elem) = 0;
};
class Container: public Icontainer
{
public:
void addElem(Melem &elem) { elem.extra(); };
//*Now* we're implementing Icontainer::addElem
};
I've got a interface that's implemented as an abstract base class with a number of pure virtual public methods. These pure virtual functions can be implemented using a template since the differences between subclasses aren't large - so my idea was to use multiple inheritance to mix-in the appropriately templated helper-class that provides the implementation. However, the compiler complains that the base class is abstract; it isn't considering the helper mix-in's implementation so thinks there's no implementation of a required method.
For example:
class TrivialList {
int count;
public:
TrivialList(int count) : count(count){}
virtual double Average() const=0;
int Count() const {return count;}
virtual ~TrivialList(){}
};
template<typename TIndexable> class AverageHelper {
public:
double Average() const {
TIndexable const & self = static_cast<TIndexable const &>(*this);
double sum=0.0;
for(int i=0;i<self.Count();++) sum += self.Get(i);
return sum / self.Count();
}
};
class IndexableList : public TrivialList, public AverageHelper<IndexableList> {
std::vector<double> backend;
public:
IndexableList(int count) : TrivialList(count), backend(count) { }
double & Get(int i) { return backend[i];}
double const & Get(int i) const { return backend[i];}
};
IndexableList * MakeList() {return new IndexableList(5);} //error!
// cannot instantiate abstract class
I'm using MSC 10.0 (Visual Studio 2010); the code fails with a similar error using g++ 4.5.
Get or the real-world equivalents in my project cannot be virtual because they're extremely minor operations that need to be inlined for adequate performance (think put-pixel/get-pixel) - so I need the generic algorithms to be templated rather than generic via virtual function calls.
For implementing mix-ins via templates, you need the template implementing the abstract function to derive from the abstract base class.
So you may fix your code by changing it the following way:
// ...
template<typename TIndexable> class AverageHelper : public TriviaList{
// ...
class IndexableList : public AverageHelper<IndexableList> {
In general, if you want to provide more than one mix-in, you may either use a virtual inheritance in order not multiplying the instances of the base classes, or to use chain inheritance as in the following sample:
class Abstract {
public:
virtual void foo() = 0;
virtual void bar() = 0;
};
template<class Base>
class FooImpl : Base {
public:
void foo() { /* default foo implementation */ }
};
template<class Base>
class BarImpl : Base {
public:
void bar() { /* default bar implementation */ }
};
class Derived : public BarImpl<FooImpl<Abstract> > {
// You have both foo() and bar() implementations available
};
It doesn't work because AverageHelper<>::Average() doesn't override TrivialList::Average(). In order to override a virtual function, the overriding class must inherit from the class containing the function to be overridden.
You could change your template thus:
template<typename TIndexable, typename Base >
class AverageHelper : public Base {
public:
template< typename T >
AverageHelper(T arg) : Base(arg) {}
// ...
};
class IndexableList : public AverageHelper<IndexableList,TrivialList> {
public:
IndexableList(int count) : AverageHelper<IndexableList,TrivialList>(count) {}
// ...
};
You might want to virtually derive from TrivialList:
template<typename TIndexable, typename Base >
class AverageHelper : virtual public Base {
// ...
};