[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Virtual functions ...

Posted on 2002-05-22
17
Medium Priority
?
231 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 200 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

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

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

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

VM backup deduplication is a method of reducing the amount of storage space needed to save VM backups. In most organizations, VMs contain many duplicate copies of data, such as VMs deployed from the same template, VMs with the same OS, or VMs that h…
Are you looking to recover an email message or a contact you just deleted mistakenly? Or you are searching for a contact that you erased from your MS Outlook ‘Contacts’ folder and now realized that it was important.
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 viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

873 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