473,769 Members | 6,473 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

function with derived class arguments

I have an error when i compile this:

class A {
public:
void f(A&) {}
};

class B: public A {
public:
void f(B&) {}
};

int main() {
A a;
B b;
b.f(a);
}

my compiler says:

no matching function for call to 'B::f(A&)'

I dont understand why the base class member function is not seen by the
compiler ?

Txn
Jun 27 '08 #1
7 1470
Icario wrote:
I have an error when i compile this:

class A {
public:
void f(A&) {}
};

class B: public A {
public:
void f(B&) {}
};

int main() {
A a;
B b;
b.f(a);
}

my compiler says:

no matching function for call to 'B::f(A&)'

I dont understand why the base class member function is not seen by the
compiler ?
Because the language definition says so.

You need to make A::f visible.

class A {
public:
void f(A&) {}
};

class B: public A {
public:
using A::f; // <------------ !!!

void f(B&) {}
};

int main() {
A a;
B b;
b.f(a);
}
Best

Kai-Uwe Bux

Jun 27 '08 #2
Icario wrote:
>
>I have an error when i compile this:

class A {
public:
void f(A&) {}
};

class B: public A {
public:
void f(B&) {}
};

int main() {
A a;
B b;
b.f(a);
}

my compiler says:

no matching function for call to 'B::f(A&)'

I dont understand why the base class member function is not seen by the
compiler ?

Because the language definition says so.
Ok but what is the reason for that ?
Jun 27 '08 #3
Icario <ic****@granama il.cmowrites:
>Icario wrote:
>>I have an error when i compile this:

class A {
public:
void f(A&) {}
};

class B: public A {
public:
void f(B&) {}
};

int main() {
A a;
B b;
b.f(a);
}

my compiler says:

no matching function for call to 'B::f(A&)'

I dont understand why the base class member function is not seen by the
compiler ?

Because the language definition says so.

Ok but what is the reason for that ?
Because A::f(A&) and B::f(B&) are totally unrelated methods. They're
so unrelated, that the compiler generates different names for them:
(see below the ==== line).
The true name of A::f(A&) is _ZN1A1fERS_ (on some compiler)
while the true name of B::f(B&) is _ZN1B1fERS_ (on same compiler)
(Or did you believe name mangling was done only to obfuscate?).

Explicitely, methods are not identified by only their names, but also
by their signature. To do what you wanted to do, you would have to
keep both the name and the signature constant:

-*- mode: compilation; default-directory: "/tmp/" -*-
Compilation started at Thu Jun 5 12:34:11

cd /tmp ; g++ -o b b.c++ && (cat b.c++ ; echo '-----------' ; ./b)
#include <iostream>
using namespace std;
class A{
public:
int f(A&){return 42;}
};
class B:public A{
public:
int f(A&){return 33;}
};
int main(void){
A a;
B b;
cout<<a.f(a)<<e ndl;
cout<<b.f(b)<<e ndl; // works too, since b is a B is a kind of A.
return(0);
}
-----------
42
33

Compilation finished at Thu Jun 5 12:34:12

In this case, we only have one signature int f(A&), and two methods,
one of which is selected according to the (static) class of the
recipient of the message. (You'd use virtual if you wanted the
dispatch to be done at run-time, on the effective (dynamic) class of
the recipient.)
=============== =============== =============== =============== ============

-*- mode: compilation; default-directory: "/tmp/" -*-
Compilation started at Thu Jun 5 12:29:10

cd /tmp ; g++ -S a.s a.c++ ; cat a.c++ a.s
class A {
public:
int f(A&) {return 42;}
};

class B: public A {
public:
using A::f;
int f(B&) { return 33;}
};

int main() {
A a;
B b;
b.f(a);
b.f(b);
}
.file "a.c++"
.section .text._ZN1A1fER S_,"axG",@progb its,_ZN1A1fERS_ ,comdat
.align 2
.weak _ZN1A1fERS_
.type _ZN1A1fERS_, @function
_ZN1A1fERS_:
..LFB2:
pushq %rbp
..LCFI0:
movq %rsp, %rbp
..LCFI1:
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movl $42, %eax
leave
ret
..LFE2:
.size _ZN1A1fERS_, .-_ZN1A1fERS_
..globl __gxx_personali ty_v0
.section .text._ZN1B1fER S_,"axG",@progb its,_ZN1B1fERS_ ,comdat
.align 2
.weak _ZN1B1fERS_
.type _ZN1B1fERS_, @function
_ZN1B1fERS_:
..LFB3:
pushq %rbp
..LCFI2:
movq %rsp, %rbp
..LCFI3:
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movl $33, %eax
leave
ret
..LFE3:
.size _ZN1B1fERS_, .-_ZN1B1fERS_
.text
.align 2
..globl main
.type main, @function
main:
..LFB4:
pushq %rbp
..LCFI4:
movq %rsp, %rbp
..LCFI5:
subq $16, %rsp
..LCFI6:
leaq -2(%rbp), %rdi
leaq -1(%rbp), %rsi
call _ZN1A1fERS_
leaq -2(%rbp), %rsi
leaq -2(%rbp), %rdi
call _ZN1B1fERS_
movl $0, %eax
leave
ret
..LFE4:
.size main, .-main
.section .eh_frame,"a",@ progbits
..Lframe1:
.long .LECIE1-.LSCIE1
..LSCIE1:
.long 0x0
.byte 0x1
.string "zPR"
.uleb128 0x1
.sleb128 -8
.byte 0x10
.uleb128 0x6
.byte 0x3
.long __gxx_personali ty_v0
.byte 0x3
.byte 0xc
.uleb128 0x7
.uleb128 0x8
.byte 0x90
.uleb128 0x1
.align 8
..LECIE1:
..LSFDE1:
.long .LEFDE1-.LASFDE1
..LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB2
.long .LFE2-.LFB2
.uleb128 0x0
.byte 0x4
.long .LCFI0-.LFB2
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI1-.LCFI0
.byte 0xd
.uleb128 0x6
.align 8
..LEFDE1:
..LSFDE3:
.long .LEFDE3-.LASFDE3
..LASFDE3:
.long .LASFDE3-.Lframe1
.long .LFB3
.long .LFE3-.LFB3
.uleb128 0x0
.byte 0x4
.long .LCFI2-.LFB3
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI3-.LCFI2
.byte 0xd
.uleb128 0x6
.align 8
..LEFDE3:
..LSFDE5:
.long .LEFDE5-.LASFDE5
..LASFDE5:
.long .LASFDE5-.Lframe1
.long .LFB4
.long .LFE4-.LFB4
.uleb128 0x0
.byte 0x4
.long .LCFI4-.LFB4
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI5-.LCFI4
.byte 0xd
.uleb128 0x6
.align 8
..LEFDE5:
.ident "GCC: (GNU) 4.1.2 (Gentoo 4.1.2 p1.0.2)"
.section .note.GNU-stack,"",@progb its

Compilation finished at Thu Jun 5 12:29:10

--
__Pascal Bourguignon__
Jun 27 '08 #4
Pascal J. Bourguignon dixit:
Icario <ic****@granama il.cmowrites:
>>Icario wrote:

I have an error when i compile this:

class A {
public:
void f(A&) {}
};

class B: public A {
public:
void f(B&) {}
};

int main() {
A a;
B b;
b.f(a);
}

my compiler says:

no matching function for call to 'B::f(A&)'

I dont understand why the base class member function is not seen by the
compiler ?
Because the language definition says so.
Ok but what is the reason for that ?

Because A::f(A&) and B::f(B&) are totally unrelated methods.
Yes. That's right. I know that.
They're
so unrelated, that the compiler generates different names for them:
(see below the ==== line).
The true name of A::f(A&) is _ZN1A1fERS_ (on some compiler)
while the true name of B::f(B&) is _ZN1B1fERS_ (on same compiler)
(Or did you believe name mangling was done only to obfuscate?).
No I did not believe that.
>
....skip unbearable assembly....
>
I was just trying to understand why the standard makes A::f(A&) hidden
(unless using artefacts as suggested) in B inherited from class A when
defining a different function (different signature) with same name.
Jun 27 '08 #5
On 5 Jun, 18:37, Icario <ica...@granama il.cmowrote:
[snip]
I was just trying to understand why the standard makes A::f(A&) hidden
(unless using artefacts as suggested) in B inherited from class A when
defining a different function (different signature) with same name.
Because of the way name lookup works in C++, and I believe it works
this way to avoid (even more) ambiguities. For instance:

#include <string>
struct B
{
void f(int) {}
void g(unsigned) {}
void h(float) {}
};
struct D : B
{
void f(std::string) {}
void g(int) {}
void h(double) {}
};

int main()
{
D d;
d.f(0); // if B's names were considered, which function should be
called here?
d.g(0u); // ,here?
d.h(0.0f); // and here?
}

Hope this helps,
DP
Jun 27 '08 #6
On Jun 5, 12:35 pm, Icario <ica...@granama il.cmowrote:
I have an error when i compile this:

class A {
public:
void f(A&) {}

};

class B: public A {
public:
void f(B&) {}

};

int main() {
A a;
B b;
b.f(a);

}

my compiler says:

no matching function for call to 'B::f(A&)'

I dont understand why the base class member function is not seen by the
compiler ?

Txn
As you are declaring a function in the derived class B with the same
name of the function present in the base class A, so derived class's
function hides the base class's function and the A::f(A&) is no more
visible for the derived class.
Jun 27 '08 #7
On Jun 5, 9:59 am, Icario <ica...@granama il.cmowrote:
Icario wrote:
I have an error when i compile this:
class A {
public:
void f(A&) {}
};
class B: public A {
public:
void f(B&) {}
};
int main() {
A a;
B b;
b.f(a);
}
my compiler says:
no matching function for call to 'B::f(A&)'
I dont understand why the base class member function is not
seen by the compiler ?
Because the language definition says so.
Ok but what is the reason for that ?
To avoid problems for the maintenance programmer. Consider
something like:

class Base
{
} ;

class Derived : public Base
{
void f( int ) ;
void g() { f( 'a' ) ; }
} ;

Obviously, as it stands, the programmer wants (and expects) the
call to f in g to go to Derived::f(). What happens if during
maintenance, a programmer adds f(char) to Base? Without name
hiding, if the new function is private, the code suddenly stops
compiling, and if it isn't, the semantics of the program
silently change (which is even worse).

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orient�e objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34
Jun 27 '08 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
3760
by: Kostatus | last post by:
I have a virtual function in a base class, which is then overwritten by a function of the same name in a publically derived class. When I call the function using a pointer to the derived class (ClassB* b; b->func(); ) the base-class function is called instead of the new function in the derived class. All other similar functions (virtual in the base class and overwritten in the the derived class) work fine, it's just this one function. ...
1
1686
by: TheOne | last post by:
I have two classes: class OntologyParser { ... protected: virtual void startElement(void *userData, const char *name, const char **atts); virtual void endElement(void *userData, const char *name);
5
5852
by: rbfish | last post by:
Hi, How can I call a virtual base function with variable parameters? like, class base { public: int printf(const char *fmt, ...) { // do anything here.
13
3663
by: George | last post by:
Hi all, I'm moving my experince from C to C++ and while so I'm facing some problems with inheritance. Here is my problem: class A { // All share attributes // ....
17
2237
by: Jef Driesen | last post by:
Suppose I have a datastructure (actually it's a graph) with one template parameter (the property P for each edge and vertex): struct graph<P>; struct vertex<P>; struct edge<P>; I also have an algorithm that modifies this datastructure. The basic outline of the algorithm is independent of the type of property. So I implemented a generic version of the algorithm and a function object for
6
2944
by: ivan.leben | last post by:
I want to write a Mesh class using half-edges. This class uses three other classes: Vertex, HalfEdge and Face. These classes should be linked properly in the process of building up the mesh by calling Mesh class functions. Let's say they point to each other like this: class Vertex { HalfEdge *edge; }; class HalfEdge { Vertex* vert;
1
1495
by: joseph cook | last post by:
I'm confused by this output. I would expect the more specific overloaded function to be selected: #include <iostream> class Base { }; class Derived : public Base {};
6
3312
by: newbie | last post by:
class AbstractBox { public: virtual double area() const = 0; } class BoxA : public AbstractBox { virtual double area() { return 0.1; } } class BoxB : public AbstractBox {
8
5536
by: Jon Harrop | last post by:
I am trying to learn C# and .NET programming in general but I am finding it very hard going. To start with, I'd like to translate some trivial functions from other languages that I am familiar with into C#. Here is a simple function in OCaml that nests "n" applications of "f" around "x", with "n" defaulting to "n=2": let rec nest ?(n=2) f x = if n=0 then x else nest ~n:(n-1) f (f x) For example, "nest f x" gives "f(f(x))" and "nest...
0
9589
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10216
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10049
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9997
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9865
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8873
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7413
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5309
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3565
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.