Вопрос

I was surprised by the output produced by the piece of code below (g++ 4.4.7).

class A {
public:
    virtual void f() {std::cout << "A::f()" << std::endl;}
};

class B : public A {
private:
    // Automatically virtual, because of base class
    void f() {std::cout << "B::f()" << std::endl;}
};

int main(int argc, const char *argv[])
{
    A *pB = new B();
    pB->f();
    return 0;
}

The output is

B::f()

I know that because of late binding the compiler cannot issue an error here, but why can we call a private method from a non-private context?

What is the rationale?

Это было полезно?

Решение

n3376 11.5.1

The access rules (Clause 11) for a virtual function are determined by its declaration and are not affected by the rules for a function that later overrides it.

11.5.2

Access is checked at the call point using the type of the expression used to denote the object for which the member function is called. The access of the member function in the class in which it was defined (D in the example above) is in general not known.

Другие советы

Access specifiers only exist for compilation purposes. Any memory within your program's allocation can be accessed by any part of the executable; there is no public/private concept at runtime

Late binding functions are run time so there is no public and private concept for run time

Actually I have tried to execute this code with little modification to make specify base
class virtual function in private section and I got error from compiler. because in compile
time first control goes to base class function but it is defined in private section so
compiler throw error . Whenever you declare a object of the derived class taking the
reference of base class. In compile time control goes to base class first and every class makes its own virtual table and then run time the pointer object invoke derived class function and no matters where it is declared private or public as I said earlier.

   class A {
         virtual void f() {std::cout << "A::f()" << std::endl;}
  };

class B : public A {
   private:
     // Automatically virtual, because of base class
      void f() {std::cout << "B::f()" << std::endl;}
 };

int main(int argc, const char *argv[])
 {
  A *pB = new B();
   pB->f();
 return 0;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top