0

Consider the following scenario: Class A defines many virtual functions. Class B and class C inherit from class A, but I want some virtual functions in class A to be available only in class B and not in class C.

I wrote the following code to try it out:

class A
{
public:
    A() { }
    virtual void play() 
    {
        printf("A::play() \n");
    }
};

class B : public A
{
public:
    B() { }
    virtual void play() = delete;
private:

};
class C : public A
{
public:
    C() { }
    virtual void play() 
    {
      
    }
private:

};

The error is as follows: error C2282: "B::play" cannot be overwritten "A::play"

sure,we can do that like this:

 class A
    {
    public:
        A() { }
        virtual void play() 
        {
            printf("A::play() \n");
        }
    };

class B : public A
{
public:
    B() { }
    
private:
    virtual void play()
    {
        printf("This function has been removed.");
    }
};
class C : public A
{
public:
    C() { }
    virtual void play() 
    {
      
    }
private:

};

However, I don't think this implementation is elegant enough.(I want class B to have no play() function, even if it's private and no one else can use it)

So, i have two questions:

  1. How to elegantly implement the scenario I envisioned
  2. Can the delete keyword not be used for virtual functions? I can't find anything that says the delete keyword cannot be used for virtual functions
lin
  • 1
  • 1
  • 3
    You can't do that. The interface of `A` is a *contract*. `A` must provide services specified therein. Every class that wishes to inherit from `A` must sign this contract. You cannot pick and choose which parts of the contracts you want to fulfill. – n. m. could be an AI Apr 20 '23 at 10:33
  • I think my scenario is reasonable. It's also possible to make the play() function private in class B, but I don't think that's elegant, and I'm looking for an elegant solution. – lin Apr 21 '23 at 01:21
  • 1
    An alternate solution would be to remove play() from A, and create a class A2 that subclasses A and adds the play() method. Then have B subclass A and C subclass A2. – Jeremy Friesner Apr 21 '23 at 02:01
  • 5
    Suppose it were possible to delete `play()` from `B`. Does this code compile: `void playme(A* a) { a->play(); }`? If not, why not? If so, then does this code compile: `playme(new B());`? If not, why not? If so, what happens when it executes? – Raymond Chen Apr 21 '23 at 03:35
  • Why not have a `void play() override { }` in `B` instead? – Tanveer Badar Apr 21 '23 at 04:28
  • 2
    No it is not. An A can play by definition, that's how being an A is defined. If a B wants to be an A, it must be able to play. If a B cannot play, it cannot be an A. There is no such thing as "an A except cannot play". C++ member function declararion models "can-do" and inheritance models "is-a". – n. m. could be an AI Apr 21 '23 at 06:05
  • "It's also possible to make the play() function private in class B" It actually solves exactly nothing, you can still call `play` through an `A*` pointing to a `B` (and calling virtual functions through base pointers is the whole point). – n. m. could be an AI Apr 21 '23 at 06:09
  • @n.m. ok, I sort of get it. Also, can you parse why the "delete" keyword can't be used for virtual functions ? – lin Apr 21 '23 at 07:07
  • It is simply not a part of the language. – n. m. could be an AI Apr 21 '23 at 07:48
  • "[A deleted function shall not override a function that is not deleted](https://timsong-cpp.github.io/cppwp/class.virtual#17)." – Raymond Chen Apr 21 '23 at 11:36

0 Answers0