Why can I call instance functions statically? - c++

I was looking around the Notepad++ source code on GitHub recently, and came across a method call like this:
Window::init(hInst, parent);
I searched for the function it was referencing to, and came across a Window class- but the init function was marked virtual, so clearly it was non-static. Thinking I made a mistake, I checked the entire header to make sure there was no static overload of init, and I made sure there was no Window.cpp file. There isn't.
After poking around the source for 15 more minutes, I gave in and git cloned the repo locally so I could open it in Visual Studio. The first thing I did was to build just to make sure this wasn't an accidental merge on behalf of the project developers- the build succeeded.
The next steps I took:
I opened the the file calling Window::init and clicked Go To Declaration on Window. It takes me to the Window class.
I clicked Go To Declaration on the init function. It points me to the signature of the virtual method.
I copy and paste the Window.h file into an entirely new header and replace all references of Window with Foo. When I type in Foo::init, the compiler complains that 'a nonstatic member reference must be relative to a specific object'.
TL;DR: Somehow, the Notepad++ source code calls a non-static method statically, and this builds. Doesn't work with any other class. Proof here and here.
I have spent 2 hours staring at this, but I still don't see how it's possible. Am I missing something?

No, it's not calling a static function. It's just calling the base class's version of init(). Basically, in tClassName::f, you are asking "I want to call that specific version of the virtual function f() in class tClassName".
Generally, it's pretty common to call the base class's counterpart of a virtual function in the derived class. E.g., the factory method pattern:
#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);
}
};

Am I missing something?
Yes - context. Notepad_plus_Window derives from Window, and the call to Window::init() is inside of the Notepad_plus_Window::init() method:
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);
...
}
In this context, Notepad_plus_Window is calling the base class Window version of init().

Maybe this will confuse you less. You're missing context, at no real fault of your own.
You're not seeing the implicit this in the call.
Take the following example:
#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;
}
In the above, we can specify the object on which to call a specific method in the class' hierarchy.

It's not a static function. It's calling a function with a specified (class) scope.
By default, init() will match functions within current class scope, if they do exist. that is an implicit this call, equals this->init(),
But with a specified class/namespace prefix, you can explicit call any particular function without dynamic binding. i.e. ::init() will call the init() function within 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;
}

Related

Override virtual method with static method

Is there any specific reason why I cannot override virtual method from base class with static one?
Anyone knows why it would be bad idea?
Example:
#include <cstdio>
class Foo
{
public:
virtual void SomeMethod() = 0;
};
class Bar : public Foo
{
public:
static void SomeMethod() override
{
printf("SomeMethod");
}
};
void SomeFunctionWithFoo( Foo *p )
{
p->SomeMethod();
}
int main()
{
Bar o;
o.SomeMethod();
SomeFunctionWithFoo( &o );
Bar::SomeMethod();
o.StaticSomeMethod();
}
Instead I have to do this:
#include <cstdio>
class Foo
{
public:
virtual void SomeMethod() = 0;
};
class Bar : public Foo
{
public:
void SomeMethod() override
{
StaticSomeMethod();
}
static void StaticSomeMethod()
{
printf("SomeMethod");
}
};
void SomeFunctionWithFoo( Foo *p )
{
p->SomeMethod();
}
int main()
{
Bar o;
o.SomeMethod();
SomeFunctionWithFoo( &o );
Bar::StaticSomeMethod();
o.StaticSomeMethod();
}
I think as long as you don't need to access member variables, your function can be static, so that it can serve behaviour without object. In the same time such static function can serve behaviour when using interface. But maybe I am wrong and I am missing something?
With one method and two classes, it is not problem, but I have case of 10 such methods inside class, and many classes that inherit.
In real world scenario, such possibility would make my code simpler.
Summary: member functions have an invisible first parameter that your static method doesn't have.
Details: Member functions (effectively) are effectively all static methods that have an "invisible" first parameter, which is the Bar* this parameter, which tells the method which instance of the class to use. So the signature of virtual void SomeMethod() is, under the covers, actually static void SomeMethod(Foo*), but static StaticSomeMethod() doesn't have the same number of parameters.
C++ is mostly able to pretend this parameter doesn't exist, but overrides are one case where it pops up. You also see it occur when trying to bind a member function to a std::function, where you have to explicitly pass the this as the first pointer.

c++, In Child class, how can access Parent class's method without a object?

I think only the static method can do the following thing, but it can works.
can anybody tell me how it works? what's the principle behind this thing.
#include <iostream>
using namespace std;
class Parent {
protected:
unsigned char* buf;
unsigned int bufLenght;
public:
void Setup()
{
buf = nullptr;
bufLenght = 0;
cout << "in Parent class Setup()" << endl;
}
virtual void TearDown()
{
delete[] buf;
}
};
class Child : public Parent{
public:
virtual void Setup()
{
Parent::Setup(); // access Parent method without a parent's object?
cout << "in Child class Setup()" << endl;
}
};
int main(int argc, char const *argv[])
{
Child co;
co.Setup();
return 0;
}
run this code, the result is :
in Parent class Setup()
in Child class Setup()
I find the answer here:
How to call a parent class function from derived class function?
and in thinking in c++, I also find the same description:
However, when you’re redefining a function, you may still want to
call the base-class version. If, inside set( ), you simply call set( )
you’ll get the local version of the function – a recursive function
call. To call the base-class version, you must explicitly name the
base class using the scope resolution operator.
Each Child object is built on top of a Parent object. Whenever you have a Child you also have a Parent.
I can't seem to understand what you're trying to achieve. It appears that you've omitted the 'virtual' keyword on the base class method you're trying to override and hence receiving errors from the compiler.
Although your question is fairly unclear, here is my best attempt at demonstrating how to implement polymorphism in C++:
class A {
protected:
// You will not be able to access this in the
// other class unless you explicitly declare it as
// a 'friend' class.
int m_ProtectedVariable;
public:
// Let's define a virtual function that we can
// override in another class.
virtual void ClassMethod( ) {
printf( "[A::ClassMethod] Called!\n" );
}
}
class B : public A {
public:
// There is no need for the virtual/override keywords
// if you are overloading the function which is already defined
// in another class as 'virtual'. I prefer to keep them for
// pedantic reasons.
/* virtual */ void ClassMethod( ) /* override */ {
//
printf( "[B::ClassMethod] Called!\n" );
// Since the function is a virtual, we can always
// call the base class function.
A::ClassMethod( /* ... */ );
}
}
Hopefully you find this helpful in whatever you're trying to achieve :-)
EDIT: In your particular scenario, where you're supposed to allocate a buffer when you need it and destroy it afterwards - why are you not making use of the class constructor/destructor functionality?
It would be far more intuitive to let the compiler decide when to manage memory (in this case) as it will happen automatically once your object goes out of scope.

C++ Compiler (cl) does not see parent virtual method with same child method name

I have a C++ code, using inheritance and function overriding at the same time, here is the code:
#include <iostream>
#include <string>
using namespace std;
class Parent
{
protected:
virtual void G() const = 0;
public:
virtual void G(const string& s) const final { G(); }
};
class Child : public Parent
{
protected:
virtual void G() const override { cout<<"Child G"; }
};
int main()
{
Child *c = new Child();
c->G("test");
return 0;
}
When compile, I got error: Child::G: function does not take 1 arguments. But when I use Parent pointer like this:
Parent *c = new Child();
It works. Alternatively if I change public G method's name, it works too.
What is wrong about using same name (G) for both methods?
You need to introduce the parent member into the child with a using declaration:
class Child : public Parent
{
protected:
virtual void G() const override { cout<<"Child G"; }
public:
using Parent::G;
};
The fix for this is indeed to introduce the Parent's method into the scope of the Child class with a using declaration, as #Jans kindly points out. As to why this is the case is simply a matter of how the compiler searches through scopes when searching for a method to match your function call. A break down of what's happening is as follows:
in Child *c = new Child(); c->G("test");, the compiler sees a call to some method G on an object of type Child. It then searches the scope of Child to look for a match.
The compiler, when exploring the scope of Child, sees only Child::G() const. It does not see Parent::G(const std::string&) const, which even though you want it to be included via inheritance, is in a different scope. In a sense, Child::G is shadowing Parent::G. Without a candidate match, the compiler would have kept searching into the Parent scope.
The compiler thus is happy having found Child::G. However, this is a function accepting no arguments, and you tried to call it with "test". The function call then fails because of a mismatch in the parameters.
As stated, you need to bring Parent::G into the same scope as Child::G for overloading to happen as intended, with using Parent::G inside the body of Child.
Source: https://isocpp.org/wiki/faq/strange-inheritance#overload-derived

c++ overriding a function only for a specific instance

I was wondering whether there's a way to override a function for a specific instance only. For ex,
class A
{
public:
...
void update();
...
}
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new A();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new A();
// ....so on.
...
}
Is there a way to achieve this?
I think virtual function is just what you want, with virtual function, different instances of the same type can have different functions, but you need to inherit the base class. for example
class A
{
public:
...
virtual void update()
{
std::cout << "Class A\n";
}
...
};
class B: public A
{
public:
virtual void update()
{
std::cout << "Class B\n";
}
};
class C: public A
{
public:
virtual void update()
{
std::cout << "Class C\n";
}
};
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new B();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new C();
// ....so on.
...
}
each instance in the above code will bind different update functions.
Besides, you can also use function pointer to implement your requirement, but it is not recommended. For example
class A
{
public:
A(void(*u)())
{
this->update = u;
}
...
void (*update)();
};
void a_update()
{
std::cout << "update A\n";
}
void b_update()
{
std::cout << "update B\n";
}
void c_update()
{
std::cout << "update C\n";
}
int main()
{
...
A first_instance(a_update);
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A second_instance(b_update);
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A third_instance(c_update);
// ....so on.
...
}
Hope helps!
Hold a function in the class.
#include <iostream>
#include <functional>
using namespace std;
class Foo
{
public:
Foo(const function<void ()>& f) : func(f)
{
}
void callFunc()
{
func();
}
private:
function<void ()> func;
};
void printFoo() { cout<<"foo"<<endl; }
void printBar() { cout<<"bar"<<endl; }
int main()
{
Foo a(printFoo);
Foo b(printBar);
a.callFunc();
b.callFunc();
}
You may have noticed that the end brace of a class is often followed by a semicolon, whereas the end braces of functions, while loops etc don't. There's a reason for this, which relates to a feature of struct in C. Because a class is almost identical to a struct, this feature exists for C++ classes too.
Basically, a struct in C may declare a named instance instead of (or as well as) a named "type" (scare quotes because a struct type in C isn't a valid type name in itself). A C++ class can therefore do the same thing, though AFAIK there may be severe limitations on what else that class can do.
I'm not in a position to check at the moment, and it's certainly not something I remember using, but that may mean you can declare a named class instance inheriting from a base class without giving it a class name. There will still be a derived type, but it will be anonymous.
If valid at all, it should look something like...
class : public baseclass // note - no derived class name
{
public:
virtual funcname ()
{
...
}
} instancename;
Personally, even if this is valid, I'd avoid using it for a number of reasons. For example, the lack of a class name means that it's not possible to define member functions separately. That means that the whole class declaration and definition must go where you want the instance declared - a lot of clutter to drop in the middle of a function, or even in a list of global variables.
With no class name, there's presumably no way to declare a constructor or destructor. And if you have non-default constructors from the base class, AFAIK there's no way to specify constructor parameters with this.
And as I said, I haven't checked this - that syntax may well be illegal as well as ugly.
Some more practical approaches to varying behaviour per-instance include...
Using dependency injection - e.g. providing a function pointer or class instance (or lambda) for some part of the behavior as a constructor parameter.
Using a template class - effectively compile-time dependency injection, with the dependency provided as a function parameter to the template.
I think it will be the best if you'll tell us why do you need to override a function for a specific instance.
But here's another approach: Strategy pattern.
Your class need a member that represent some behaviour. So you're creating some abstract class that will be an interface for different behaviours, then you'll implement different behaviours in subclasses of that abstract class. So you can choose those behaviours for any object at any time.
class A;//forward declaration
class Updater
{
public:
virtual ~Updater() {};//don't forget about virtual destructor, though it's not needed in this case of class containing only one function
virtual void update(A&) = 0;
}
class SomeUpdater
{
public:
virtual void update(A & a);//concrete realisation of an update() method
}
class A
{
private:
Updater mUpdater;
public:
explicit A(Updater updater);//constructor takes an updater, let's pretend we want to choose a behaviour once for a lifetime of an object - at creation
void update()
{
mUpdater.update(this);
}
}
You can use local classes, yet, personally, I consider the "hold function in the class" approach mentioned in the other answer better. I'd recommend the following approach only if doFunc must access internals of your base class, which is not possible from a function held in a member variable:
class ABase {
public:
void Func () { this->doFunc (); }
private:
virtual void doFunc () = 0;
public:
virtual ~ABase () { }
};
ABase* makeFirstA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "First A"; }
};
return new MyA;
}
ABase* makeSecondA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "Second A"; }
};
return new MyA;
}
int main () {
std::shared_ptr<ABase> first (makeFirstA ());
std::shared_ptr<ABase> second (makeSecondA ());
first->Func ();
second->Func ();
}
From a design patterns point of view, the "local classes" approach implements the template method pattern, while the "hold a function(al) in a member variable" approach reflects the strategy pattern. Which one is more appropriate depends on what you need to achieve.

Polymorphic Member Variable

I got an elegant answer yesterday for my question regarding polymorphic object members.
But now I am facing the problem that the variable isn't really behaving the way I expected it to. The following code is being used:
#include <iostream>
#include <math.h>
using std::cin;
using std::cout;
using std::endl;
class Com
{
public:
virtual void setReady()
{
cout << "Com" << endl;
}
};
class DerivedCom : public Com
{
public:
void setReady()
{
cout << "DCom" << endl;
}
void somethingElse()
{
cout << "else" << endl;
}
};
class BaseClass
{
public:
Com* com;
public:
BaseClass(Com* c = new Com) : com(c)
{
}
virtual void setReady()
{
com->setReady();
}
};
class DerivedClass : public BaseClass
{
// the call to somethingElse() won't compile if I leave out this declaration
protected:
DerivedCom* com;
public:
DerivedClass() : BaseClass(new DerivedCom)
{
}
void setReady()
{
// This line causes a segfault if I put in the declaration earlier
this->com->setReady();
// This line won't compile if I leave out the declaration earlier
this->com->somethingElse();
}
};
int main()
{
DerivedClass* inst = new DerivedClass();
inst->setReady();
return 0;
}
The problem is, that DerivedClass::com is in fact of type DerivedCom but I can't access any DerivedCom-specific methods as the compiler won't find them. If I put in an extra re-declaration DerivedCom* com, the compiler will find the methods but I get segmentation faults.
Remove that extra declaration.
If you are sure that a Com* is a DerivedCom* then you can static_cast it.
static_cast<DerivedCom*>(this->com)->somethingElse();
This will likely crash it you're wrong however. So if you are not sure then you can dynamic_cast it
DerivedCom* dcom = dynamic_cast<DerivedCom*>(this->com);
if (dcom)
dcom->somethingElse();
dynamic_cast will return NULL if the object isn't of the type you asked for.
The reason for the segmentation faults is that you arent declaring the variable again with a different type, you are actually defining a new pointer in the derived class, one that is never initialized. Thus this->com->... will access the derived class com and crash since it is an uninitialized pointer.
What you are trying to do though, is to change the type of the member pointer. You could do that by making the type of the member pointer as a template variable, as follows
template <class ComType>
class BaseClassTemplate
{
ComType* com;
...;
};
typedef BaseClassTemplate<Com> BaseClass;
class DerivedClass : public BaseClassTemplate<DerivedCom>
{
...;
};
However this makes the base class a template, so to get it as you want it, you need to make an instantiation of BaseClass<Com> to get your version of base class. You can either make it a derived class or just a typedef as i have shown.