Basic problem with Inheritance

M

Matthias Pfeifer

Hi there,

i am implementing a Point and Vector class and found that they have some
things in common. Therefore i introduced a common parent class called
ndimobj, that hosts an array of n values, offers some constructors and
the following operator

template<size_t n, typename T>
class ndimobj
{
<SNIP>
public:
ndimobj<n, T>& operator= (const T s);
};

ndimobj is templated by the type of the elements that live in a given "n
dimensional space" (doubles, polynomials, etc...) and the dimension n.

Point is now derived from ndimobj like this

template<size_t n=3, typename T=float>
class Point : public ndimobj<n, T>
{
public:
double distance(Point<n,T> p)
{ <snip> }
};

If i do (in a test) program

Point <4, double> q;
q=3.0;

my compiler (g++) complains:

test.cc: 49: error no match for 'operator=' in 'q=3.0e+0'
Point.hpp: 22: note: candidates are: Point<4u, double>& Point<4u,
double>::eek:perator=(const Point<4u, double>&)

Why is operator= not known. and why does g++ find this unsuitable
candidate?!
Please let me know if didn't give sufficiently information and i'll post
the complete interface of ndimobj and Point if it helps.

Thanks in advance

matthias
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Hi there,

i am implementing a Point and Vector class and found that they have some
things in common. Therefore i introduced a common parent class called
ndimobj, that hosts an array of n values, offers some constructors and
the following operator

template<size_t n, typename T>
class ndimobj
{
<SNIP>
public:
ndimobj<n, T>& operator= (const T s);
};

ndimobj is templated by the type of the elements that live in a given "n
dimensional space" (doubles, polynomials, etc...) and the dimension n.

Point is now derived from ndimobj like this

template<size_t n=3, typename T=float>
class Point : public ndimobj<n, T>
{
public:
double distance(Point<n,T> p)
{ <snip> }
};

If i do (in a test) program

Point <4, double> q;
q=3.0;

my compiler (g++) complains:

test.cc: 49: error no match for 'operator=' in 'q=3.0e+0'
Point.hpp: 22: note: candidates are: Point<4u, double>& Point<4u,
double>::eek:perator=(const Point<4u, double>&)

Why is operator= not known. and why does g++ find this unsuitable
candidate?!
Please let me know if didn't give sufficiently information and i'll post
the complete interface of ndimobj and Point if it helps.

Because you have not defined the = operator, what exactly do you expect
q=3.0; to do? If this was a point in the mathematical sense what would
that statement mean? Nothing as far as I know, you can't assign a scalar
to a vector (an a point is a vector as far as math is concerned).

The candidate found by gcc is used like this:

Point <4, double> p;
Point <4, double> q;
p = q;

this = operator is automatically generated by the compiler for your
convenience.
 
M

Matthias Pfeifer

Because you have not defined the = operator,

my ndimobj class has "operator= (const T s)" shouldn't class Point have
that inhereted?

template<size_t n, typename T>
class ndimobj
{
<SNIP>
public:
ndimobj<n, T>& operator= (const T s);
};

matt
 
L

LR

Matthias said:
my ndimobj class has "operator= (const T s)" shouldn't class Point have
that inhereted?

template<size_t n, typename T>
class ndimobj
{
<SNIP>
public:
ndimobj<n, T>& operator= (const T s);
};


The compiler will generate a Point &operator=(const Point &).


Consider this code:

class A {
public:
A &x(const int x) {
return *this;
}
};

class B : public A {
public:
B &x(const B &x) {
return *this;
}
};

int main() {
B q;
B p;
q.x(1); // error
q.x(p);
}

LR
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

my ndimobj class has "operator= (const T s)" shouldn't class Point have
that inhereted?

template<size_t n, typename T>
class ndimobj
{
<SNIP>
public:
ndimobj<n, T>& operator= (const T s);
};

Sorry, missed that. No it will not inherit that, you should get the same
error when trying to compile this:

struct A {
A& operator=(int i_);
};

struct B : public A {
};

int main() {
B b;
b = 1;
}
 
F

Frank Birbacher

Hi!

Matthias said:
Why is operator= not known.

There is something called "hiding" base class members. This is what is
happening here. Because the Point class has the automatically generated
"operator = (Point const&)" for self assignment, the base class
"operator =" is hidden. You can make it visible again by a "using"
declaration:

//in class Point
using ndimobj<n, T>::eek:perator =;

HTH,
Frank
 
M

Matthias

Frank said:
Hi!



There is something called "hiding" base class members. This is what is
happening here. Because the Point class has the automatically generated
"operator = (Point const&)" for self assignment, the base class
"operator =" is hidden. You can make it visible again by a "using"
declaration:

//in class Point
using ndimobj<n, T>::eek:perator =;

HTH,
Frank

thank you all for your answers. Using
> using ndimobj<n, T>::eek:perator =;

my compiler is satisfied - i am however not. I know about copy
constructors, which should be the automagically generated "Point<n,
T>::eek:perator= (Point const&)". I am confused, because "my" operator is
"ndimobj<n, T>::eek:perator= (const T)". Where i like to point that he has
a completely different argument (not const Point&, but const T). Please.
Why is the operator hidden?

sincerely
Matthias
 
B

BobR

LR said:
class A {
public:
A &x(const int x) {
return *this;
}
};

class B : public A {
public:
B &x(const B &x) {
return *this;
}
};

int main() {
B q;
B p;
q.x(1); // error
q.x(p);
}

LR

Thanks for the spaces vs. tabs. Looks like it should now (indented). <G>
 
F

Frank Birbacher

Hi!
my compiler is satisfied - i am however not. I know about copy
constructors, which should be the automagically generated "Point<n,
T>::eek:perator= (Point const&)".

In fact, this is not a "constructor". It is the (automatically
generated" "assignment operator". The copy constructor is
Point said:
I am confused, because "my" operator is
"ndimobj<n, T>::eek:perator= (const T)". Where i like to point that he has
a completely different argument (not const Point&, but const T). Please.
Why is the operator hidden?

Hiding is not about argument types. This is not like overloading. Hiding
is solely done by function NAME. In your case the function name is
"operator =". And "Point" has its own "operator =" (automatically
generated) which hides the "ndimobj::eek:perator ="s (both, yours and the
automatic one).

Example:

struct Base
{
void foo();
};

struct Dev : Base
{
void foo(int);
};

int main()
{
Dev d;
d.foo(); //error
}

"void Base::foo()" is hidden by "void Dev::foo(int)" although they have
different arguments and may otherwise be overloads.


struct Base2
{
void foo();
};

struct Dev2 : Base2
{
using Base2::foo;
void foo(int);
};

int main()
{
Dev d;
d.foo(); //works
}

Here the "using Base2::foo" makes the base class functions visible
again. Now "foo" is an overloaded function.

Your case (simplified):

struct ndimobj
{
//ndimobj& operator = (ndimobj const&); //automatic
ndimobj& operator = (int); //your operator =
};

struct Point : ndimobj
{
//this "operator =" hides "operator =" of ndimobj:
//Point& operator = (Point const&); //automatic
};

The automatic operator = in Point hides the base class operator =.

HTH,
Frank
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,202
Messages
2,571,055
Members
47,658
Latest member
jaguar32

Latest Threads

Top