Why can I call instance functions statically?

I recently searched for the source code of Notepad ++ on GitHub, and met a method invocation method as follows:

Window::init(hInst, parent);

I looked for the function that I referenced and came across a Windowclass, but the function initwas marked virtualso that it was non-stationary. Thinking that I made a mistake, I checked the entire header to make sure there was no static overload init, and I made sure that there was no file Window.cpp. This is not true.

After you scroll through the source code for another 15 minutes, I handed over the git clonedrepo locally to open it in Visual Studio. The first thing I did was build only to make sure that this was not an accidental merger on behalf of the project developers - the assembly was successful.

The following steps I have taken:

  • I opened the file calling Window::initand clicked Go To Declarationon Window. This leads me to class Window.

  • I clicked Go To Declarationon a function init. He points me to the signature of the virtual method.

  • I copy and paste the file Window.hinto a completely new header and replace all links Windowwith Foo. When I type Foo::init, the compiler complains that "the reference to the non-static member must be relative to a specific object."

TL; DR:. - Notepad ++ , . - . .

2 , , . - ?

+4
4

, . init(). , tClassName::f : " f() tClassName".

, . , factory:

#include "tObject.h"
#include "tObject1.h" // public inheritance from tObject
#include "tObject2.h" // public inheritance from tObject
#include "tObject3.h" // public inheritance from tObject

class BaseFactory
{
public:
   // factory method
   virtual tNode *createObject(int id)
   {
      if (id == 1) return new tObject1;
      else return new tObject2;
   }
};

class DerivedFactory: public BaseFactory
{
public:
   virtual tNode *createObject(int id)
   {
      // Overrides the default behavior only for one type
      if (id == 1) return new tObject3;
      // Call the default factory method for all other types
      else return BaseFactory::createObject(id);
   }
};
+2

- ?

- . Notepad_plus_Window Window, Window::init() Notepad_plus_Window::init():

class Notepad_plus_Window : public Window { 
public: 
    ...
    void init(HINSTANCE, HWND, const TCHAR *cmdLine, CmdLineParams *cmdLineParams); 
    ...
};

void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLine, CmdLineParams *cmdLineParams) 
{ 
    ...
    Window::init(hInst, parent); 
    ...
}

Notepad_plus_Window Window init().

+2

, . , .

this .

:

#include <cstdio>
#include <iostream>

class Foo {
public:
  virtual void bar() {
    std::cout << "Foo" << std::endl;
  }
};

class Bar : public Foo {
public:
  virtual void bar() {
    std::cout << "Bar" << std::endl;
  }
};

int main() {
  Bar bar;
  bar.bar();        //-> bar
  bar.Foo::bar();   //-> foo

  Bar *barp = &bar;
  barp->bar();      //-> bar
  barp->Foo::bar(); //-> foo

  return 0;
}

, .

+1

. () .

init() , . , this- > init(),

But with the specified class / namespace prefix, you can explicitly call any particular function without dynamic binding. i.e. :: init () will call the init () function in the global scope.

The following code may give you a better understanding.

#include <iostream>

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

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

int main()
{
    A* a = new B();
    a->A::test();
    return 0;
}
+1
source

Source: https://habr.com/ru/post/1599205/


All Articles