Solved

Virtual functions ...

Posted on 2002-05-22
17
222 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
Use Case: Protecting a Hybrid Cloud Infrastructure

Microsoft Azure is rapidly becoming the norm in dynamic IT environments. This document describes the challenges that organizations face when protecting data in a hybrid cloud IT environment and presents a use case to demonstrate how Acronis Backup protects all data.

 

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
 
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

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

How to update Firmware and Bios in Dell Equalogic PS6000 Arrays and Hard Disks firmware update.
The article will include the best Data Recovery Tools along with their Features, Capabilities, and their Download Links. Hope you’ll enjoy it and will choose the one as required by you.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

770 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