I am having some trouble getting some overloaded operators working correctly with a simple inherited Vector class (numerical vector, not container) The scalar multiply from the base class doesn't appear to be visible to the derived class. Code follows:

Base Class Header

#pragma once

#include <vector>

class Base
{
protected:
    std::vector<double> val;
public:
    Base();
    Base( double v0, double v1, double v2 );
    virtual ~Base(){}
    virtual Base operator*( const double scalar ) const;
};

Base Class Implementation

#include "base.h"

using namespace std;

Base::Base(){
    val = vector<double>( 3, 0.0 );
}

Base::Base( double v0, double v1, double v2 ){
    val = vector<double>( 3, 0.0 );
    val[0] = v0;
    val[1] = v1;
    val[2] = v2;
}


Base Base::operator*( const double scalar ) const{
    return Base( val[0] * scalar, val[1] * scalar, val[2] * scalar );
}

Derived Class Header

#pragma once

#include "base.h"

class Derived : public Base{
public:
    Derived();
    Derived( double a, double b, double c );
    Derived( const Base &other );
    virtual ~Derived(){}
    double a() const;
    double b() const;
    double c() const;

    double operator*( const Derived& other ) const;
};

Derived Class Implementation

#include "derived.h"

Derived::Derived() : Base(){}

Derived::Derived( double a, double b, double c ) : Base(a,b,c){}

Derived::Derived( const Base &other ) : Base(other){}

double Derived::a() const{
    return val[0];
}

double Derived::b() const{
    return val[1];
}

double Derived::c() const{
    return val[2];
}

double Derived::operator*( const Derived& other ) const{
    return val[0] * other.val[0] + val[1] * other.val[1] + val[2] * other.val[2];
}

Main Program

#include <vector>
#include "base.h"
#include "derived.h"

using namespace std;

int main(int argc, char *argv[])
{
    Derived d, e;
    e = d * 1.0;
    return 0;
}

Compiler Output

main.cpp: In function ‘int main(int, char**)’:
main.cpp:15: error: no match for ‘operator*’ in ‘d * 1.0e+0’
derived.h:15: note: candidates are: double Derived::operator*(const Derived&) const

Recommended Answers

All 10 Replies

bump.

Please help, I can't seem to find a good explanation of why this is happening, and it's keeping me 2 steps away from actually my application. This is a dummy example that is a simplified version of what is going wrong with my greater application. The thing about this that bothers me most is that when I remove the

double Derived::operator*( const Derived& other ) const;

function from the derived class, the scalar multiply works fine. Please help, thanks.

Please don't bump your threads so soon, have a bit of patience. I was actually just about to give you: e = d.Base::operator*(1.0); I'm fairly sure that in cases like this you lose the more aesthetic syntax, but I believe that this works.

Let me spell it out to you :

main.cpp: In function ‘int main(int, char**)’:
Inside your main function
main.cpp:15: error: no match for ‘operator*’ in ‘d * 1.0e+0’

There is no matching function function in the call :"e = d * 1.0;"

derived.h:15: note: candidates are: double Derived::operator*(const Derived&) const

It even says it here, the only valid function is "double Derived::operator*(const Derived&) const"

Let me spell it out to you :

main.cpp: In function ‘int main(int, char**)’:
Inside your main function
main.cpp:15: error: no match for ‘operator*’ in ‘d * 1.0e+0’

There is no matching function function in the call :"e = d * 1.0;"

derived.h:15: note: candidates are: double Derived::operator*(const Derived&) const

It even says it here, the only valid function is "double Derived::operator*(const Derived&) const"

Please don't talk down to me. I am quite capable of reading a compiler error verbatim. However, I am not sure why the declaration of the dot product operator (Derived::operator*) is seeming to collide with the scalar product operator (Base::operator*). Neither have the same return type or parameter signature, so it seems that there should be no collision. I would really like to use the * operator in the Base class ( a generic triple scaling operation ) for all derived classes ( such as Vectors, Points, and Colors ) and overload the * operator for each as is suitable. For example, a dot product of two Vectors is a reasonable operation, but a dot product of two Colors makes no sense. Can there be only one operator overload for a given class heirarchy?

Fair enough. You have to downcast the derived to base class.

e = dynamic_cast<Base&>(d) * 1.0;

I was afraid of that. Downcasting pretty much ruins the aethetic elegance of operator overloading in this case. I think I'll just use a

double Derived::dotProd( Derived& other );

Just curious, are you creating a 2d and 3d vector class.

Just curious, are you creating a 2d and 3d vector class.

Yes, they are 3d vector classes that I am using in a custom built raytracer. I implemented it in Python last year, now I'm moving it over to c++.

I just used an explicit dot product function. Not as satisfying aesthetically, but functional. Thanks for the help.

// Simple solution:
class Derived : public Base {
public:
...
using Base::operator*; // make all things in Base named operator* visible (and public) in Derived's scope
...
};

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.