Hi,
I have abstract base class with some kids deriving from it. I want its kids to be concrete classes But I don't want to implement the all methods of the class. I'm trying to find a trick to go around doing this and I'm running out of thought on this. below is illustrative code of what I want to do.

Thanks for your help

class BaseDB {
	BaseDB();
	virtual ResultSet getResults()=0;
	virtual void setResults(std::string sql)=0;
	virtual void someMoreFunction()=0;

};


class FirstChild :public BaseDB {
	ResultSet getResults(){
		//do some stuffs
	}
	
	void setResults(std::string sql){
		//some more stuffs
	}
	
	//I don't want to implement someMoreFunction() in this class
}

class SecondChild :public BaseDB {
	ResultSet getResults(){
		//do some stuffs
	}
	
	void someMoreFunction(){
		//some more stuffs
	}
	
	//I don't want to implement setResults(std::string sql) in this class
}

What do you want to happen when you do this?

SecondChild sc;
sc.setResults("foo");

and how do you want what happens to differ from what happens when you do this?

BaseDB b;
b.setResults("foo");

In both cases, you're trying to call a member function that isn't defined.

>I want its kids to be concrete classes But I don't want to implement the all methods of the class.
Oddly enough we just had a discussion about this. You can make the "optional" member functions simply virtual instead of pure virtual (all with no-op bodies). Then include a pure virtual destructor in the base class to make it abstract if there are no more pure virtuals left in the base class.

It's not a perfect solution, but depending on your actual needs as opposed to the description you've given, it may be suitable.

What do you want to happen when you do this?

SecondChild sc;
sc.setResults("foo");

and how do you want what happens to differ from what happens when you do this?

BaseDB b;
b.setResults("foo");

In both cases, you're trying to call a member function that isn't defined.

I want them to be dummy functions, because Child classes will choose which one to implement. If they implement some of them and leave some, it will still be abstract class. So I'm finding a way to implement a sort of "default" function in case user doesn't want.
I just have no Idea how to make those dummy/default functions.

>I want its kids to be concrete classes But I don't want to implement the all methods of the class.
Oddly enough we just had a discussion about this. You can make the "optional" member functions simply virtual instead of pure virtual (all with no-op bodies). Then include a pure virtual destructor in the base class to make it abstract if there are no more pure virtuals left in the base class.

It's not a perfect solution, but depending on your actual needs as opposed to the description you've given, it may be suitable.

seem something i'm looking for :)
What do you mean by "all with no-op bodies"

>What do you mean by "all with no-op bodies"
An empty body, such that when the member function is called, it returns immediately with some suitable default:

virtual ResultSet getResults() { return ResultSet(); }

Edited 6 Years Ago by Narue: n/a

>What do you mean by "all with no-op bodies"
An empty body, such that when the member function is called, it returns immediately with some suitable default:

virtual ResultSet getResults() { return ResultSet(); }

I want default value to be NULL so that whenever I encounter NULL I know that there is no implementation for this function. I wonder If NULL will be suitable for function that returns some type of value (Non void functions)

Your problem is that those function do not belong in you abstract class. It seems like you are not abstracting enough, if you want only
some function of the base class to be implemented. Whats wrong with simply letting the child develop the necessary functions? You might
not necessarily need polymorphism depending on your problem. If you want state your problem and we'll be glad to help.

Edited 6 Years Ago by firstPerson: n/a

Your problem is that those function do not belong in you abstract class. It seems like you are not abstracting enough, if you want only
some function of the base class to be implemented. Whats wrong with simply letting the child develop the necessary functions? You might
not necessarily need polymorphism depending on your problem. If you want state your problem and we'll be glad to help.

FP,
It is kind of plugin app. The Plugins *must* implement some methods and other are *optional*. So I don't want to force them to implement optional features. The issue is Plugin manager when loading the plugin instances, it casts them to pointer to Abstract class. For that manner if method isn't defined in AC, then I cannot use it, you see.

Those functions are specializations. Why not just put them in the child objects? That way you don't have to worry about how to avoid implementing them for the classes you don't want to have them. It's a basic principle of the inheritance mechanism. They don't have to exist in the base class to be accessible from derived objects.

Edited 6 Years Ago by Fbody: n/a

> I want default value to be NULL so that whenever I encounter NULL
> I know that there is no implementation for this function.
> I wonder If NULL will be suitable for function that returns some type of value

There are two ways that you can simulate this behaviour.

1. Have the function return a discriminated union which could be null;
for example boost::any http://www.boost.org/doc/libs/1_42_0/doc/html/any.html
And have the default implementation return null.

2. The default implementation of the function does not return; it throws.

#include <iostream>
#include <boost/any.hpp>
#include <stdexcept>

struct not_implemented_error : std::runtime_error
{
    explicit not_implemented_error()
              : std::runtime_error( "function not implemented." ) {}
};

struct base
{
    virtual boost::any foo() { return boost::any() ; }
    virtual int bar() const
    {
        throw not_implemented_error() ;
        return 0 ; // for compilers which may complain otherwise 
    }
    protected : virtual ~base() = 0 ;
};

base::~base() {}

struct one : base // does not implement bar
{
    virtual boost::any foo() { return 100 ; }
} ;

struct two : base // does not implement foo
{
    virtual int bar() const { return 200 ; }
} ;

void test_it( base* object )
{
    boost::any result  = object->foo() ;
    if( result.empty() )
        std::cerr << "object->foo(): function not implemented\n" ;
    else
        std::cout << "object->foo() returns " << boost::any_cast<int>(result) << '\n' ;

    try
    {
        std::cout << "object->bar() returns " << object->bar() << '\n' ;
    }
    catch( const std::exception& error )
    {
        std::cerr << "object->bar(): " << error.what() << '\n' ;
    }
}

int main()
{
    one a ; test_it(&a) ;
    two b ; test_it(&b) ;
}
This question has already been answered. Start a new discussion instead.