Solved

Virtual functions ...

Posted on 2002-05-22
17
220 Views
Last Modified: 2013-11-18
The next code must work, but it doesn'work. Why ????

I have 2 classes ISender and ISend. Look below.

class ISender
{
public:
     ISender() {}
     virtual ~ISender() {}

     virtual bool send(string &str,
                          int len,
                          int type,
                          int prior
                         )
     {
       return true;
     }    

};

class ISend : public ISender
{
public:
     ISend() {}
     virtual ~ISend() {}

     virtual bool send(string &str)
     {
      return true;
     }
};

void Test()
{
 ISend senderr;
 string rrr("Rostik");

 // Compiler doesn't see this function ???
 senderr.send(rrr, 1,2,3);


 senderr.send(string("rrr"));
}

0
Comment
Question by:Rostik
  • 8
  • 5
  • 4
17 Comments
 
LVL 3

Accepted Solution

by:
MDarling earned 50 total points
ID: 7026507
class ISend : public ISender
{
public:
    ISend() {}
    virtual ~ISend() {}

    ISender::send;

    virtual bool send(string &str)
    {
     return true;
    }
};
0
 
LVL 3

Expert Comment

by:MDarling
ID: 7026516

#include <string>
#include <iostream>

using namespace std;

class ISender
{
public:
    ISender() {}
    virtual ~ISender() {}
    virtual bool send(string &str,
                      int len,
                      int type,
                      int prior
        )
    {
        cout << "ISender::send\n";
        return true;
    }    
};
class ISend : public ISender
{
public:
    ISend() {}
    virtual ~ISend() {}

    ISender::send;

    virtual bool send(string &str)
    {
        cout << "ISend::send\n";
        return true;
    }
};

void Test()
{
    string s("rrr");
    ISend senderr;
    string rrr("Rostik");
// Compiler doesn't see this function ???
    senderr.send(rrr, 1,2,3);
    senderr.send(s);
}

int main()
{
    Test();
    return 0;
}



the Isend class' send is "hiding" the ISender class' send.  To make it visible you use...

Isender::send;

or using Isender::send;

Regards.
Mike.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7026554
Or add this function to your ISend class:

     virtual bool send(string &str, int len, int type, int prior )
    {
          return ISender::send (str, len, type, prior );
    }    

-- Dan
0
 

Author Comment

by:Rostik
ID: 7026678
Thanks !!!!!!!!!!!!!
0
 
LVL 3

Expert Comment

by:MDarling
ID: 7026760
Hi Dan,

Does your response not mean one extra function call?

Also what if he had several send functions with different parameter lists in his base class?  You'd need to wrap each one...

Regards,
Mike.
0
 
LVL 3

Expert Comment

by:MDarling
ID: 7026761
Rostik - does this answer your question?

If so, you should close the question by accepting the comment that solves the problem as an answer.

Regards,
Mike.
0
 

Author Comment

by:Rostik
ID: 7026793
Thanks ....
0
 

Author Comment

by:Rostik
ID: 7026841
This is work on PC. HP doesn't except " ISender::send; " ????????????
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 3

Expert Comment

by:MDarling
ID: 7026891
try ...

class ISend
{
...
using ISender::send;
...
};


if that doesn't work I'd suspect your compiler is old.

Regards,
Mike.


0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7027697
My solution is better.
-- Dan
0
 
LVL 3

Expert Comment

by:MDarling
ID: 7027937
Hi Dan,

In what way is your solution better?

Is is better to do 2 function calls instead of 1?

Is it better to have to provide wrapper functions each time he adds a new send function to the base class?

Mike
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7028242
It's better because it is easy to understand, does not require any unusual syntax, and (a minor bonus) it is better because it works.  

Other than that, I can't think of anything.

-- Dan
0
 
LVL 3

Expert Comment

by:MDarling
ID: 7028335
But it isn't better code is it?

I omitted "using" in the 1st instance cos the major compilers on windows/linux don't need it - that was an omission I'll grant.

However the syntax is only "unusual" until you know what it does, like any syntax thats unfamiliar.

It is standard C++, however.

That said - you're code means doing 2 function calls and incurs overhead because of it.  Also, anytime you add a new send overload to the base class you have to wrap it in the derived class.

Is it better to do this or learn "unusual" syntax?

In case you haven't guessed - I think my solution is better :-)

Best regards,
Mike.

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7028376
MDarling,
It's a new syntax to me.  Are you saying that just this:

      Isender::send;

in the class def for a derived class brings in all overloads of the base class's send fn into the new class and makes them directly usable in code without needing to use namespace scope, as if they were all defined in the derived class?  If so, your syntax is better.

Out of curiosity, what if you have a variable named

   int send;

in the base class?

-- Dan
0
 
LVL 3

Expert Comment

by:MDarling
ID: 7028412
Hi Dan,

>It's a new syntax to me.  Are you saying that just this:
>
>     Isender::send;
>
>in the class def for a derived class brings in all >overloads of the base class's send fn into the new
>class and makes them directly usable in code without >needing to use namespace scope, as if they were
>all defined in the derived class?  If so, your syntax is >better.

Yes, if they aren't private (and the class is not derived privately).  Though from now on I'm putting in the using keyword :-)  It's to get round the hiding nature of derivation in this case.  If he had not declared an overloaded send function in the derived class then his base send function would have been visible.  The fact he overloaded it meant that the base one was hidden.

>Out of curiosity, what if you have a variable named
>
>  int send;
 
I think that would be a compiler error - you can't have a function and variable with the same name in the same scope.

Regards,
Mike.
0
 

Author Comment

by:Rostik
ID: 7028996
I found in the MSDN library an explanation. You can find it, just look for topic - "using declaration".
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7029069
I am finding this exceedingly odd.  If the
     ISender::send;
comes after the declaration of the 1-parm send() in the derived, then I get syntax errors.  Put it before the 1-parm send() and it works as described.  Also, the syntax can only be used to access members of the direct base (not ancestors).

For anyone else who reads this and is interested, the syntax is discussed under the topic

   'using Declaration'

in MSDN.  It appears the the reason for it is... to do exactly what is desired in this question: unhide an overloaded member function that lives in a base class, so that it can be used without a bunch of awkward decorations in the source code.  

It seems to act as if the declaration gets copied from the base class, into the derived class.  If there are two overloaded send(...) fns in the base class, then both of them are now incorporated into, and become available as, members of the derived class.

MDarling,
My original syntax, which appears to be foolishly wasteful (a function calling a function) turns out be quite efficient after a good optimizer gets hold of it.  The compiler actually 'optimizes away' all of the overhead and just performs the base-class function directly.

So I'm still leaning toward the opinion that some quirky trick with namespaces is less than ideal.  I know that if I were to ever code myself into that corner, I would use the straightforward, easy-to-read, easy-to-understand solution.  

But then, I never got the hang of rocket-jumping in  Quake, either :)

-- Dan
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

How to fix error ""Failed to validate the vCentre certificate. Either install or verify the certificate by using the vSphere Data Protection Configuration utility" when you are trying to connect to VDP instance from Vcenter.
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now