Hi all,

I have an issue with a piece of code that I am writing. The problem I'm facing is that I have a base class and a derived class, and the base class contains a pure virtual function. I then want to overload the pure virtual function with a non-virtual function in the base class, with the implementation of the non-virtual function including a call to the pure virtual function. When I try to run this, the compiler seems to overwrite the overloaded function with the implementation of the pure virtual function in the derived class, and hence cannot execute the call to the non-virtual function.

I have googled this issue, and come across it on a few websites, but I don't totally understand the explanations given, nor the appropriate solution for what I want to do. Most websites I've looked at that address this issue point to the following webpage as reference: http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.6.

I'm not quite sure what the explanation there means for what I want to do though, and it doesn't cover the issue of inheritance along with virtual function overloading.

I've included a bit of example code to explain the problem I want to solve:

class BaseClass
{
public:
    void setInputParameter()
    {
        inputParameter_ = inputParameter;
    }
    
    void computeFunction( const double& inputParameter )
    {
        setInputParameter( inputParameter );
        this->computeFunction();
    }
protected:
    virtual void computeFunction() =0;
private:
    inputParameter_;
}

class DerivedClass : public BaseClass
{
public:
   void computeFunction()
    {
        fooVariable_ = 20.0;
    } 
protected:
private:
    double fooVariable_;
}

I hope someone can help me sort this out.

Thanks in advance,

Cheers,

Kartik

I'm not sure what you are asking for. But Do you want to call Base::computeFunction() inside of Derived::computeFunction()

The problem is that you need to have the same access right for the overwritten function in the derived class, otherwise, the compiler will call the public function first. So, simple correction:

class BaseClass
{
public:
    void setInputParameter()
    {
        inputParameter_ = inputParameter;
    }
    
    void computeFunction( const double& inputParameter )
    {
        setInputParameter( inputParameter );
        this->computeFunction();
    }
protected:
    virtual void computeFunction() =0;
private:
    inputParameter_;
}

class DerivedClass : public BaseClass
{
protected: //see here, make this function protected to match the base class.
   void computeFunction()
    {
        fooVariable_ = 20.0;
    } 

private:
    double fooVariable_;
}

I'm not sure what you are asking for. But Do you want to call Base::computeFunction() inside of Derived::computeFunction()

Ok I want to make an object and do the following:

DerivedClass derivedClassObject;

derivedClassObject.computeFunction();

derivedClassObject.computeFunction( 1.0 );

The problem is that the first second line works and the third one doesn't. The compiler throws an error with the third line saying a function of that form can't be found.

Cheers,

Kartik

>>saying a function of that form can't be found.
This is because if you have a non-virtual function in the base class and a non-virtual function of the same name in the derived class it will "hide" the one in the base class and the compiler won't find it.

>>saying a function of that form can't be found.
This is because if you have a non-virtual function in the base class and a non-virtual function of the same name in the derived class it will "hide" the one in the base class and the compiler won't find it.

Yup exactly, and apparently it even overwrites the function if it's overloaded, which doesn't make sense to me.

So how do I do this so that the overloaded function can also be used?

I can't make the computeFunction in the derived class protected because I have to be able to access it as a public function.

Cheers,

Kartik

>>I can't make the computeFunction in the derived class protected because I have to be able to access it as a public function.

Then make it public in the base class and in the derived class.

In other words, all the overloaded functions (virtuals and non-virtuals) of a name need to be in the same class.

>>I can't make the computeFunction in the derived class protected because I have to be able to access it as a public function.

Then make it public in the base class and in the derived class.

In other words, all the overloaded functions (virtuals and non-virtuals) of a name need to be in the same class.

I've made the change of making all the computeFunction functions public.

I still get the compiler error that computeFunction( 1.0 ) cannot be called because that form of the function is not known to the compiler.

Cheers,

Kartik

I just verified in my own code, and I use this extensively in my code so I know this works. Are you sure this is what you have:

class BaseClass
{
public:
    void setInputParameter()
    {
        inputParameter_ = inputParameter;
    }
    
    void computeFunction( const double& inputParameter )
    {
        setInputParameter( inputParameter );
        this->computeFunction();
    }
    virtual void computeFunction() =0;
private:
    inputParameter_;
}

class DerivedClass : public BaseClass
{
public:
   void computeFunction()
    {
        fooVariable_ = 20.0;
    } 

private:
    double fooVariable_;
}

Oh, wait, I just remembered, you have to cast to the base class to call the overloaded functions of the base class:

DerivedClass derivedClassObject;

derivedClassObject.computeFunction();

BaseClass& baseClassRef = derivedClassObject;
baseClassRef.computeFunction( 1.0 );

Oh, wait, I just remembered, you have to cast to the base class to call the overloaded functions of the base class:

DerivedClass derivedClassObject;

derivedClassObject.computeFunction();

BaseClass& baseClassRef = derivedClassObject;
baseClassRef.computeFunction( 1.0 );

I haven't tried that fix, but there's a problem with that already, in that it's an end-user that has to be using this object. So for user-friendliness, I need to be able to run both versions of compute function as I gave in my second code example.

Cheers,

Kartik

You want the using declarative :

#include <iostream>

using namespace std;

struct B{
	void p(){ cout << "Base p()\n";}
};
struct D: B{
	using B::p;
	void p(int i){ cout << "Derived p(" << i  << ")\n";}
};

int main(){	
	D d;
	d.p();
	d.p(1);
}

You want the using declarative :

#include <iostream>

using namespace std;

struct B{
	void p(){ cout << "Base p()\n";}
};
struct D: B{
	using B::p;
	void p(int i){ cout << "Derived p(" << i  << ")\n";}
};

int main(){	
	D d;
	d.p();
	d.p(1);
}

That works!

The only question I have is if this is performance-wise the best solution? Are there solutions that are faster performance-wise?

Thanks a lot,

Cheers,

Kartik

>>The only question I have is if this is performance-wise the best solution? Are there solutions that are faster performance-wise?

You don't need to worry about performance at this stage. Your bottleneck is likely to
be somewhere else. I wouldn't see why this is bad. Your not casting things. You are
simply telling the compiler that you don't want to hide the function of the base
class.

>>The only question I have is if this is performance-wise the best solution? Are there solutions that are faster performance-wise?

You don't need to worry about performance at this stage. Your bottleneck is likely to
be somewhere else. I wouldn't see why this is bad. Your not casting things. You are
simply telling the compiler that you don't want to hide the function of the base
class.

I wasn't sure if there was anything performance-loss associated with it, so I just thought I'd ask. As for performance not being something to worry about, actually I do, since I'm setting up some large-scale simulations, and I'm trying now to optimise the inner loop. This belongs to that inner loop.

Thanks for resolving this for me!

Cheers,

Kartik

I wasn't sure if there was anything performance-loss associated with it, so I just thought I'd ask. As for performance not being something to worry about, actually I do, since I'm setting up some large-scale simulations, and I'm trying now to optimise the inner loop. This belongs to that inner loop.

Thanks for resolving this for me!

Cheers,

Kartik

Thats one of the worst things you can do. You should first write the best code you
can, while making it readable and clear. Then test out the program. If its not fast enough
then you need to use a profiler to find out where the bottleneck is. Then go on from there.
Again, take my advice and don't sacrifice good code with premature optimizations.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.