I got stuck with a C++ compilation error while doing something that is probably not really "conventional".
To make things easier I just re-wrote the mechanism I am trying to use in a easier-to-read way and I checked that I got the same issue.
First of all here is the code:
test.h // -- C++ --
template <typename MODULE> class item;
template <typename MODULE>
class init {
public:
typedef int (MODULE::*funcPtr)(int);
private:
funcPtr m_fp;
public:
init& has_funcPtr(funcPtr fp) { m_fp = fp;}
init() {}
virtual ~init() {}
private:
friend class item<MODULE>;
};
template <typename MODULE>
class item {
public:
typedef int (MODULE::*funcPtr)(int);
private:
funcPtr m_fp;
public:
item(init<MODULE> params) : m_fp(params.m_fp) {}
virtual ~item() {}
};
class user {
public:
typedef init<user>::funcPtr funcPtr;
private:
// Method CB
int func1(int i);
// Item member
item<user> m_item;
public:
user();
virtual ~user();
};
test.cpp // -- C++ --
#include "test.h"
user::user() : m_item(init<user>().has_funcPtr(this->func1) ) {}
int user::func1(int i) {return 1;}
and here is the error:
/test.cpp:5:59: error: invalid use of non-static member function
user::user() : m_item(init<user>().has_funcPtr(this->func1) ) {
^
So, I am not sure this is the best way to achieve what I want (probably not, anyway if you have other suggestions they are very welcome) but my goal now is to make it work or to understand exactly why it can't work so that I learn something from it!
The basic idea is that:
the class "item" can be initialized with the named parameter idiom using the method "has_funcPtr" of the class "init" concatenated to its constructor like: "init().has_funcPtr(&function_name)".
the class "user" can store a pointer to its private method "func1" as a private member of its private member of type "item".
In this way, when a specific method of an object "item" is called (for simplicity I don't include this long part here since it is not relevant to the error but it is just to describe the goal of this snippet of code) that method can do stuff and call the private method of its father object "user" through that pointer to function (I hope this is clear enough...).
Now, I think there is an issue with the order of initialization of the objects but I am not sure where and how to fix it.
In particular I thought that since the "func1" method doesn't operate on any member of the class "user", then its reference could be used directly in the initialization list to initialize an "init" object and feed it to an "item" object.
Thank you all in advance
this->func1 doesn't form a member function pointer. It should look like &user::func1 if you are in the user class.
I post here the complete answer to my issue. I developed it after the suggestion from Bo and after understanding how to point to an instance specific method through a pointer to it.
In short, two things are really important to note:
A pointer to a non-static class member function could be thought at as just an offset rather than an "absolute address" (http://www.codeguru.com/cpp/cpp/article.php/c17401/C-Tutorial-PointertoMember-Function.htm). This means that you can't access that function (it is just an offset) without first having an instance pointer. Once you have the instance pointer, with this "offset pointer" you can call that method using:
(object_ptr->*method_ptr)(parameters_here)
A better way would be to use a #define macro since this syntax is really error prone and complex to read (https://isocpp.org/wiki/faq/pointers-to-members):
#define CALL_MEMBER_FN(ptrToObject,ptrToMember) ((ptrToObject)->*(ptrToMember))
and then use it as:
CALL_MEMBER_FN(object_ptr, method_ptr)(parameters_here)
Following the first point, if you want a nested class to be able to call the upper class method by a pointer to it, you also need to pass the upper class instance pointer to access that function. In my case, since I wanted to be able to decide case by case if that method should be called or not, I used the Named Parameter Idiom (below note that func2 is not registered for example).
Finally here is the revised code that it works (tested):
-- C++ -- test.h
#include <iostream>
template <typename MODULE> class item;
template <typename MODULE>
class init {
public:
typedef int (MODULE::*funcPtr)(int);
typedef bool (MODULE::*func2Ptr)(bool);
private:
funcPtr m_fp;
func2Ptr m_fp2;
MODULE* m_dad;
public:
init& has_funcPtr(funcPtr fp) { m_fp = fp; return *this;}
init& has_func2Ptr(func2Ptr fp2) { m_fp2 = fp2; return *this;}
init(MODULE* dad) : m_dad(dad) { std::cout << "init constructor called\n"; }
~init() {}
private:
friend class item<MODULE>;
};
template <typename MODULE>
class item {
public:
typedef int (MODULE::*funcPtr)(int);
typedef bool (MODULE::*func2Ptr)(bool);
private:
funcPtr m_fp;
func2Ptr m_fp2;
MODULE* m_dad;
public:
item(init<MODULE> params) :
m_fp(params.m_fp),
m_fp2(params.m_fp2),
m_dad(params.m_dad)
{
std::cout << "item constructor called\n";
}
~item() {}
// Method invoked externally
int callback() {
std::cout << "item class method callback invoked\n";
// In the real case here do general stuff
if(m_fp) {
int i = (m_dad->*m_fp)(1); // call member function through its pointer
return i;
} else {
std::cout << "callback not registered\n";
return 0;
}
}
// Method invoked externally
bool callback2() {
std::cout << "items class method callback2 invoked\n";
// In the real case here do general stuff
if(m_fp2) {
bool b = (m_dad->*m_fp2)(true); // call member function through its pointer
return b;
} else {
std::cout << "callback2 not registered\n";
return false;
}
}
};
class user {
public:
typedef init<user>::funcPtr funcPtr;
private:
// Methods that optionally add more functionalities to the 2 callbacks
int func1(int i);
bool func2(bool b);
public:
// Item member
item<user> m_item;
public:
user();
~user();
};
-- C++ -- test.cpp
#include "test.h"
user::user() : m_item(init<user>(this).has_funcPtr(&user::func1) ) {
std::cout << "user constructor called\n";
}
int user::func1(int i) {return i;}
bool user::func2(bool b) {return b;} // func2 won't be registered
int main() {
user* u = new user();
// Test callbacks
int i = u->m_item.callback();
bool b = u->m_item.callback2();
std::cout << "main is printing i=" << i << " and b=" << b << "\n";
std::cout << "expected results are i=1 and b=0\n" << "END\n";
return 0;
}
OUTPUT:
init constructor called
item constructor called
user constructor called
item class method callback invoked
items class method callback2 invoked
callback2 not registered
main is printing i=1 and b=0
expected results are i=1 and b=0
END
Related
I am designing support for custom hooks in existing C++ class.
class NotMyClass {
public:
void DoSomething() {
// Needs custom logic here.
hook_.DoSomethingCustom();
}
protected:
Hook hook_;
int not_my_class_inner_variable_1_;
Node not_my_class_inner_variable_2_;
...... More Class vars.....
}
class Hook {
public:
void DoSomethingCustom() {
// Some custom logic that needs to access not_my_class_inner_variable_1_, not_my_class_inner_variable_2 etc. .
}
}
Adding some more context here after initial comments: NotMyClass class is autogenerated and no custom logic can be added to this class. We want to be able to add custom hooks inside the autogenerated classes. So the plan was to instead pass/ingect in a Hook class that will be able to provide some custom processing. The autogenerated NotMyClass class will have hook_. DoSomethingCustom().
What's the best way to access NotMyClass member variables inside Hook ?
I don't want to change the class structure(that is use inheritence) of NotMyClass due to additional constraints.
Is making Hook a friend of NotMyClass a good option and then passing NotMyClass as this to Hook functions ?
Thanks in advance!
The problem cannot be solved as stated, i.e., without breaking the Open-Closed-Principle (OCP), which says that "classes (and other things) should be open for extension but closed for modification." In this case, this means that you shouldn't try to both (a) leave MyClass unchanged and (b) access its private or protected members from outside. Private (or protected) signal things that are not accessed from the outside, that's literally what private (or protected) are designed for. You can circumvent this (old ways, new ways) but you shouldn't.
The answer by sanitizedUser modifies MyClass, which is undesirable as per the question. A hacky but straight-forward suggestion to your problem might be to pass the fields to be modified explicitly to the method by reference:
class MyClass {
public:
void DoSomething() {
// Pass references to the fields you want to modify.
hook_.DoSomethingCustom(my_class_inner_variable_1_, my_class_inner_variable_2_);
}
protected:
Hook hook_;
int my_class_inner_variable_1_;
Node my_class_inner_variable_2_;
}
class Hook {
public:
void DoSomethingCustom(int &inner_variable_1, Node& inner_variable_2_) {
// Use the data members.
}
}
To signal that your Hook class explicitly is allowed to access members of MyClass, you could declare it as a friend. Example:
#include <iostream>
class Node {};
class MyClass;
class Hook {
public:
void DoSomethingCustom(MyClass &m);
};
class MyClass {
friend Hook; // Allows the Hook class to access our members!
public:
MyClass(Hook h): hook_(h) {}
void DoSomething() {
// Pass references to the fields you want to modify.
hook_.DoSomethingCustom(*this);
}
void print_my_class_inner_variable_1_() {
std::cout << my_class_inner_variable_1_ << std::endl;
}
protected:
Hook hook_;
int my_class_inner_variable_1_;
Node my_class_inner_variable_2_;
};
void Hook::DoSomethingCustom(MyClass &m) {
// Allowed to access private member because we are a friend!
m.my_class_inner_variable_1_ = 42;
}
int main() {
MyClass c{Hook{}};
c.print_my_class_inner_variable_1_();
c.DoSomething();
c.print_my_class_inner_variable_1_();
}
Note: your whole design with this "Hook" looks very weird to me. How do you "add hooks" to this thing (which imho is one of the defining requirements for calling something a "hook")? I'm sure if you posted a lot more context, people here would suggest a very different larger-scale design.
It's not an ideal solution but if you are allowed to declare the Hook class a friend of NotMyClass then the following code somewhat works.
#include <iostream>
class NotMyClass;
class Hook {
public:
void DoSomethingCustom(const NotMyClass& c);
};
class NotMyClass {
friend Hook;
public:
void DoSomething() {
hook_.DoSomethingCustom(*this);
}
protected:
Hook hook_;
int not_my_class_inner_variable_1_;
// Commenting Node member out because the definition of it is missing.
// Node not_my_class_inner_variable_2_;
};
void Hook::DoSomethingCustom(const NotMyClass& c) {
std::cout << c.not_my_class_inner_variable_1_ << '\n';
}
int main() {
NotMyClass{}.DoSomething();
return 0;
}
Output.
0
If you can modify NotMyClass entirely then I advice you to use polymorphism and declare Hook as an abstract class. This way its behaviour can be swapped more easily.
#include <iostream>
#include <string>
template<class State>
struct Hook {
virtual State run(const State& s) const = 0;
};
struct ExampleState {
int number;
std::string text;
};
std::ostream& operator<<(std::ostream& stream, const ExampleState& state) {
stream << state.number << ", " << state.text << '\n';
return stream;
}
struct ExampleHook : public Hook<ExampleState> {
ExampleState run(const ExampleState& s) const override;
};
class Receiver {
public:
void DoSomething();
Receiver(const Hook<ExampleState>* const hook);
private:
const Hook<ExampleState>* const hook;
ExampleState state;
};
ExampleState ExampleHook::run(const ExampleState& s) const {
// Returning a modified state.
return {
s.number + 1,
"Modified " + s.text
};
}
void Receiver::DoSomething() {
std::cout << "Original state:\n" << this->state;
this->state = this->hook->run(this->state);
std::cout << "Modified state:\n" << this->state;
}
Receiver::Receiver(const Hook<ExampleState>* const hook)
: hook(hook), state{0, "hello"} {}
int main() {
ExampleHook hook;
Receiver receiver(&hook);
receiver.DoSomething();
return 0;
}
Output.
Original state:
0, hello
Modified state:
1, Modified hello
One way of doing this is declaring data members of class MyClass public and then passing a reference to an instance of MyClass to an instance of Hook.
class MyClass {
public:
void DoSomething() {
// Pass a reference to this.
hook_.DoSomethingCustom(*this);
}
public:
Hook hook_;
int my_class_inner_variable_1_;
Node my_class_inner_variable_2_;
}
class Hook {
public:
void DoSomethingCustom(const MyClass& c) {
// Use the data members.
auto& ref1 = c.my_class_inner_variable_1_;
auto& ref2 = c.my_class_inner_variable_2_;
}
}
If you cannot declare the members public because this is a legacy code, then there is always the evil option.
#define protected public
// Your code.
#undef protected
However, if this code is already compiled as a dynamic library then you are out of luck.
I want using polymorphism in C++, I am try to extract method shows in all derived class into base class.
For example:
I have two class, HouseA and HouseB, they are template class.
And they are derived from base class BaseHouse.
class BaseHouse
{
public:
//other thing
private:
};
template <typename Type>
class HouseA : public BaseHouse
{
public:
HouseA(Type object_input) : object(object_input)
{
}
// other thing about HouseA
Type &getObject()
{
std::cout << "this is House A" << std::endl;
return object;
}
private:
Type object;
};
template <typename Type>
class HouseB : public BaseHouse
{
public:
HouseB(Type object_input) : object(object_input)
{
}
// other thing about HouseB
Type &getObject()
{
std::cout << "this is House B" << std::endl;
return object;
}
private:
Type object;
};
Bacause of polymorphism, we using base class's pointer to access derivated class object. When I need to call method defined in derivated class, I am always transfer base class pointer into derivated class pointer:
int main()
{
HouseA<int> house_a(5);
int x = house_a.getObject();
BaseHouse *base_ptr = &house_a;
// suppose after some complicate calculate calculation
// we only have the base class pointer can access derivated class object
HouseA<int> *ptr_a = (HouseA<int> *)base_ptr; //transfer base class pointer into derivated class pointer
ptr_a->getObject();
return 0;
}
But the derived class HouseA and HouseB both have the method getObject.
So I want to extract template derived class's method into non-template base class.
For some reason, we suppose that the base class BaseHouse can not be template class.
Is there any way I can do that?
Thanks in advance.
If the signature of the derived member depends on the template arguments (as your getObject does on Type) the member cannot be extracted into a non-template base. At least not without removing the ability of the member's signature to vary based on template arguments.
Maybe not exactly a classical Visitor, but...
Okay, the basic idea is we have to somehow capture and encapsulate templated processing into a single entity ready-to-use in a run-time polymorphic construct.
Let's start with a simple class hierarchy:
struct Consumer;
struct Base {
virtual void giveObject(Consumer const &) const = 0;
virtual ~Base() = default;
};
struct Derived1: Base {
Derived1(int x): x(x) {}
void giveObject(Consumer const &c) const override {
c(x);
}
private:
int x;
};
struct Derived2: Base {
Derived2(double y): y(y) {}
void giveObject(Consumer const &c) const override {
c(y);
}
private:
double y;
};
So far, it is very simple: the Base class has a pure virtual method that accepts an object of type Consumer and a concrete implementation of this method is expected to expose to Consumer the relevant part of the internal state of its particular implementor (which is a subtype of Base). In other words, we have taken that 'virtual template' idiom and hid it inside the Consumer. Ok, what could it possibly be?
First option, if you know in advance at compile-time (at source code-time, more exactly) what it could possibly do, i.e. there's only one algorithm of consumption per each object type, and the set of types is fixed, it is quite straightforward:
struct Consumer {
void consume(int x) const { std::cout << x << " is an int.\n"; }
void consume(double y) const { std::cout << y << " is a double.\n"; }
template<typename T> void consume(T t) const {
std::cout << "Default implementation called for an unknown type.\n";
}
};
etc.
More elaborate implementation would allow run-time construction of a templated entity. How is that even possible?
Alexandrescu in his "Modern C++ Design" uses typeid to store particular type handlers in a single data structure. In a brief, this could be something like:
struct Handler {
virtual ~Handler() = default; // now it's an empty polymorphic base
};
template<typename T> struct RealHandler: Handler {
RealHandler(std::function<void(T)> f): f(std::move(f)) {}
void handle(T x) {
f(x);
}
private:
std::function<void(T)> f;
};
#include <map>
#include <type_info>
#include <functional>
struct Consumer {
template<typename T> void consume(T t) const {
auto f{knownHandlers.find(typeid(t))};
if(f != knownHandlers.end()) {
RealHandler<T> const &rh{
dynamic_cast<RealHandler<T> const &>(*f->second)};
rh.handle(t);
}
else {
// default implementation for unregistered types here
}
}
template<typename T> Consumer ®ister(std::function<void(T)> f) {
knownHandlers[typeid(T)] = std::make_unique<RealHandler<T>>(std::move(f));
}
private:
std::map<std::type_info, std::unique_ptr<Handler>> knownHandlers;
};
Haven't actually tested it, as I don't like typeids and other RTTI much. What I have quickly tested is another solution that requires neither maps nor typeinfo to store handlers in a templated manner. Still it uses a small trick, like how can we possibly pass, keep and retrieve information of an arbitrary type with the same call.
struct Consumer {
Consumer() {}
template<typename T> void consume(T t) const {
auto f{setSlot<T>()};
if(f) f(t);
else {
// default implementation for an unset slot
std::cout << t / 2 << '\n';
}
}
template<typename T>
std::function<void(T)> &setSlot(
std::function<void(T)> f = std::function<void(T)>{}) const
{
static std::function<void(T)> slot;
if(f) { // setter
slot = std::move(f);
}
return slot;
}
};
Here, setSlot() is used to store a handler for a particular type: when called with a non-empty argument, it stores that argument; and then returns its currently kept value. With Consumer so defined, the class hierarchy from above works as:
int main() {
Consumer c;
c.setSlot<int>([](int x){ std::cout << x << " is an int!\n"; });
Base const &b1{Derived1{42}};
Base const &b2{Derived2{3.14}};
b1.giveObject(c);
b2.giveObject(c);
}
Output:
42 is an int!
1.57
In the first line we see a message printed by a custom int handler; in the second line, a default message is printed for the double type, as no custom handler for double was installed.
One obvious drawback of this implementation is that handlers are stored in static variables thus all Consumers share the same handlers for all types, so Consumer here is actually a monostate. At least, you can change implementations for types at run-time, unlike if you had fixed Consumers of the very first approach. The maps-of-typeids approach from above shouldn't have this drawback, in exchange for some performance cost.
I have a base interface, declaration like this - IBaseTest.h:
#pragma once
template <class T1>
class IBaseTest
{
public:
virtual ~IBaseTest();
virtual T1 DoSomething() = 0;
};
And two children who overrides DoSomething() CBaseTest1 claass in - BaseTest1.h:
#pragma once
#include "IBaseTest.h"
class CBaseTest1: public IBaseTest<int>
{
public:
virtual int DoSomething();
};
BaseTest1.cpp:
#include "BaseTest1.h"
int CBaseTest1::DoSomething()
{
return -1;
}
And CBaseTest2 in - BaseTest2.h
#pragma once
#include "IBaseTest.h"
class CBaseTest2: public IBaseTest<long long>
{
public:
virtual long long DoSomething();
};
BaseTest2.cpp:
#include "BaseTest2.h"
long long CBaseTest2::DoSomething()
{
return -2;
}
So CBaseTest1::DoSomething() overrides return type to int, and CBaseTest2::DoSomething() to long long. Now, i want to use a pointer to the base interface, to work with those classes, and there i have the problem:
#include "IBaseTest.h"
#include "BaseTest1.h"
#include "BaseTest2.h"
int _tmain(int argc, _TCHAR* argv[])
{
IBaseTest<T1> * pBase = NULL;
pBase = new CBaseTest1();
cout << pBase->DoSomething() << endl;
pBase = new CBaseTest2();
cout << pBase->DoSomething() << endl;
getchar();
return 0;
}
The problem is i cannot declare IBaseTest<T1> * pBase = NULL; T1 is undefined. If declare the template before _tmain like this:
template <class T1>
int _tmain(int argc, _TCHAR* argv[])
{
...
}
I get: error C2988: unrecognizable template declaration/definition
So what do i put here instead of T1?
IBaseTest<??> * pBase = NULL;
The problem is that T1 parameter needs to be known when you instantiate an object of the template class IBaseTest. Technically, IBaseTest<int> and IBaseTest<long long> are two different types without a common base and C++ does not allow you to declare a variable IBaseTest<T1> pBase = NULL; where T1 is determined at runtime. What you are trying to achieve is something that would be possible in a dynamically typed language, but not in C++ because it is statically typed.
However, if you know the expected return type of DoSomething whenever you call that method, you can sort of make your example to work. First, you need to introduce a common base class that is not a template:
#include <typeinfo>
#include <typeindex>
#include <assert.h>
class IDynamicBase {
public:
virtual std::type_index type() const = 0;
virtual void doSomethingVoid(void* output) = 0;
template <typename T>
T doSomething() {
assert(type() == typeid(T));
T result;
doSomethingVoid(&result);
return result;
}
virtual ~IDynamicBase() {}
};
Note that it has a template method called doSomething that takes a type parameter for the return value. This is the method that we will call later.
Now, modify your previous IBaseTest to extend IDynamicBase:
template <class T1>
class IBaseTest : public IDynamicBase
{
public:
std::type_index type() const {return typeid(T1);}
void doSomethingVoid(void* output) {
*(reinterpret_cast<T1*>(output)) = DoSomething();
}
virtual T1 DoSomething() = 0;
virtual ~IBaseTest() {}
};
You don't need to change CBaseTest1 or CBaseTest2.
Finally, you can now write the code in your main function like this:
IDynamicBase* pBase = nullptr;
pBase = new CBaseTest1();
std::cout << pBase->doSomething<int>() << std::endl;
pBase = new CBaseTest2();
std::cout << pBase->doSomething<long long>() << std::endl;
Note that instead of calling pBase->DoSomething(), we now call pBase->doSomething<T>() where T is a type that must be known statically where we call the method and we provide that type at the call site, e.g. pBase->doSomething<int>().
The language does not allows to do directly what you are trying to do. At that point, you should ask yourself if that is the right solution for the problem.
The first approach that might work well assuming that you don't have too much different operations to do for each type would be to simply do the action in the function itself instead of returning type that are not related through inheritance.
class IBaseTest
{
public:
virtual void OutputTo(std::ostream &os) = 0;
};
class CBaseTest1
{
public:
virtual void OutputTo(std::ostream &os) override;
private:
int DoSomething();
};
void CBaseTest1OutputTo(std::ostream &os)
{
os << DoSomething() << std::endl;
}
If you have only a few types but a lot of operation, you might use the visitor pattern instead.
If you mainly have operation that depends on type, you could use:
class IVisitor
{
public:
virtual void Visit(int value) = 0;
virtual void Visit(long value) = 0;
};
Otherwise, use that which is more general
class IVisitor
{
public:
virtual void Visit (CBaseTest1 &test1) = 0;
virtual void Visit (CBaseTest2 &test2) = 0;
};
Then in your classes add an apply function
class IBaseTest
{
public:
virtual void Apply(IVisitor &visitor) = 0;
};
In each derived class, you implement the Apply function:
void CBaseTest1 : public IBaseTest
{
virtual void Apply(IVisitor &visitor) override
{
visitor.Visit(this->DoSomething()); // If you use first IVisitor definition
visitor.Visit(*this); // If you use second definition
};
And for creation purpose, you could have a factory that return the appropriate class from a type tag if you need to create those class from say a file…
One example assuming you want a new object each time:
enum class TypeTag { Integer = 1, LongInteger = 2 };
std::unique_ptr<IBaseTest> MakeObjectForTypeTag(TypeTag typeTag)
{
switch (typeTag)
{
case TypeTag::Integer : return new CBaseTest1();
case TypeTag::LongInteger : return new CBaseTest2();
}
}
So the only time you would do a switch statement is when you are creating an object… You could also use a map or even an array for that...
The right approach depends on your actual problem.
How many CBaseClass* do you have?
Do you expect to add other classes? Often?
How many operations similar to DoSomething() do you have?
How many actions that works on the result of DoSomething do you have?
Do you expect to add other actions? Often?
By responding to those questions, it will be much easier to take the right decision. If the action are stables (and you only have a few one), then specific virtual functions like OutputToabove is more appropriate. But if you have dozen of operation but don't expect much changes to ITestBase class hierarchy, then visitor solution is more appropriate.
And the reason why a given solution is more appropriate in a given context is mainly the maintenance effort when adding classes or actions in the future. You typically want that the most frequent change (adding a class or an action) require les changes everywhere in the code.
I'm trying to get a variety of Nodes to run a defined execute function that is passed in to a constructor and stored (and called) from a function pointer variable.
class Node{
std::string(*execute)();
};
Node::Node(std::string(*funcPointer)()){
execute = funcPointer;
}
I also have several derived classes that all also have an execute funcion
class redNode : public Node{
std::string execute();
};
std::string redNode::execute(){
return "I'm red";
}
class blueNode : public Node{
std::string execute();
};
std::string blueNode::execute(){
return "I'm red";
}
Then, I want to call all of the Node's execute functions.
std::string myFunc(){
return "my Func";
}
Node mynode = new Node(&myFunc);
//other instantiations here...
myRedNode.execute();
myBlueNode.execute();
myNode.execute();
However, trying to call .execute() of myRedNode or myBlueNode doesn't work because the execute variable that's a part of the parent class was never set and it seems to be calling that. Trying to then set the execute variable
myBlueNode.execute = &BlueNode::execute;
gives a error C2659: '=' function as left operand, even when I rename the function I'm setting the variable to.
How do I solve this problem? How do correctly call function with a same name as a parent class function pointer?
&BlueNode::execute is not just a function pointer. It's a member function pointer. It can be used by this way:
std::string (BlueNode::*pf)();
pf = &BlueNode::execute;
BlueNode obj;
(obj.*pf)();
But this forces the function to be member of specific class, and I think you don't want it (If so, you would just use virtual function.)
I suggest use std::function<>.
class Node
{
std::function<std::string()> execute;
public:
Node(std::function<std::string()> _execute)
: execute(std::move(_execute))
{
}
};
You can use normal functions, member functions, functors and lambda.
std::string f1() { return "f1"; }
struct T { std::string f2() { return "f2"; } };
struct F { std::string operator ()() const { return "f3"; } };
T obj;
Node n1 { f1 };
Node n2 { std::bind(&T::f2, &obj) };
Node n3 { F() };
Node n4 { []() { return std::string("f4"); } };
(live example)
First of all, &BlueNode::execute isn't a function pointer, it's a pointer to member function. To you &BlueNode::execute you also need a class pointer to use it on. For instance:
std::string (BlueNode::*memberFunctionPointer)();
memberFunctionPointer = &BlueNode::execute;
BlueNode blueNode;
(blueNode.*memberFunctionPointer)();
To do what you want(set a variable in the parent to call an arbitrary function), you would need to use std::function and std::bind to collect an instance and member function pointer, which #ikh has explained, or if that's not what you really want to do, you can also change the pointer in the parent to be a member function pointer and call it on the instance of the child, or you could use virtual functions to do that automatically.
Now the second problem that you are having, why is it giving error C2659: '=' function as left operand when you try to do myBlueNode.execute = &BlueNode::execute; is because the derived class methods execute are hiding the parent variable execute. To access the hidden variable you need to access the object as the parent type by casting it. Here is an example, just using a stand alone function:
#include <iostream>
#include <string>
class Base
{
public:
Base(std::string (*funcPointer)()) { execute = funcPointer; }
std::string (*execute)();
};
std::string StandaloneExecute()
{
return std::string("StandaloneExecute");
}
class Derived: public Base
{
public:
Derived() : Base(StandaloneExecute) {}
std::string execute() //this hides the parent execute
{
return std::string("Derived::Execute");
}
};
int main() {
Derived d;
std::cout << d.execute() << std::endl; //this will print Derived::Execute
std::cout << static_cast<Base>(d).execute() << std::endl; //this will print StandaloneExecute
return 0;
}
IDEONE
I understand the meaning of 'this', but I can't see the use case of it.
For the following example, I should teach the compiler if the parameter is the same as member variable, and I need this pointer.
#include <iostream>
using namespace std;
class AAA {
int x;
public:
int hello(int x) { this->x = x;}
int hello2(int y) {x = y;} // same as this->x = y
int getx() {return x;}
};
int main()
{
AAA a;
a.hello(10); // x <- 10
cout << a.getx();
a.hello2(20); // x <- 20
cout << a.getx();
}
What would be the use case for 'this' pointer other than this (contrived) example?
Added
Thanks for all the answers. Even though I make orangeoctopus' answer as accepted one, it's just because he got the most vote. I must say that all the answers are pretty useful, and give me better understanding.
Sometimes you want to return yourself from an operator, such as operator=
MyClass& operator=(const MyClass &rhs) {
// assign rhs into myself
return *this;
}
The 'this' pointer is useful if a method of the class needs to pass the instance (this) to another function.
It's useful if you need to pass a pointer to the current object to another function, or return it. The latter is used to allow stringing functions together:
Obj* Obj::addProperty(std::string str) {
// do stuff
return this;
}
obj->addProperty("foo")->addProperty("bar")->addProperty("baz");
In C++ it is not used very often. However, a very common use is for example in Qt, where you create a widget which has the current object as parent. For example, a window creates a button as its child:
QButton *button = new QButton(this);
When passing a reference to an object within one of its methods. For instance:
struct Event
{
EventProducer* source;
};
class SomeContrivedClass : public EventProducer
{
public:
void CreateEvent()
{
Event event;
event.source = this;
EventManager.ProcessEvent(event);
}
};
Besides obtaining a pointer to your own object to pass (or return) to other functions, and resolving that an identifier is a member even if it is hidden by a local variable, there is an really contrived usage to this in template programming. That use is converting a non-dependent name into a dependent name. Templates are verified in two passes, first before actual type substitution and then again after the type substitution.
If you declare a template class that derives from one of its type parameters you need to qualify access to the base class members so that the compiler bypasses the verification in the first pass and leaves the check for the second pass:
template <typename T>
struct test : T {
void f() {
// print(); // 1st pass Error, print is undefined
this->print(); // 1st pass Ok, print is dependent on T
}
};
struct printer {
void print() { std::cout << "print"; }
};
struct painter {
void paint() { std::cout << "paint"; }
};
int main() {
test<printer> t; // Instantiation, 2nd pass verifies that test<printer>::print is callable
t.f();
//test<painter> ouch; // 2nd pass error, test<painter>::print does not exist
}
The important bit is that since test inherits from T all references to this are dependent on the template argument T and as such the compiler assumes that it is correct and leaves the actual verification to the second stage. There are other solutions, like actually qualifying with the type that implements the method, as in:
template <typename T>
struct test2 : T {
void f() {
T::print(); // 1st pass Ok, print is dependent on T
}
};
But this can have the unwanted side effect that the compiler will statically dispatch the call to printer::print regardless of whether printer is a virtual method or not. So with printer::print being declared virtual, if a class derives from test<print> and implements print then that final overrider will be called, while if the same class derived from test2<print> the code would call printer::print.
// assumes printer::print is virtual
struct most_derived1 : test<printer> {
void print() { std::cout << "most derived"; }
};
struct most_derived2 : test2<printer> {
void print() { std::cout << "most derived"; }
};
int main() {
most_derived1 d1;
d1.f(); // "most derived"
most_derived2 d2;
d2.f(); // "print"
}
You can delete a dynamically created object by calling delete this from one of its member functions.
The this pointer is the pointer to the object itself. Consider for example the following method:
class AAA {
int x;
public:
int hello(int x) { some_method(this, x);}
};
void somefunc(AAA* a_p)
{
......
}
class AAA {
int x;
public:
int hello(int x) { this->x = x;}
int hello2(int y) {x = y;} // same as this.x = y
int getx() {return x;}
void DoSomething() { somefunc(this); }
};
this is implicit whenever you use a member function or variable without specifying it. Other than that, there are many, many situations in which you'll want to pass the current object to another function, or as a return value.
So, yeah, it's quite useful.
Sometimes you need to refer to "this" object itself, and sometimes you may need to disambiguate in cases where a local variable or a function parameter shadows a class member:
class Foo {
int i;
Foo* f() {
return this; // return the 'this' pointer
}
void g(){
j(this); // pass the 'this' pointer to some function j
}
void h(int i) {
this->i = i; // need to distinguish between class member 'i' and function parameter 'i'
}
};
The two first cases (f() and g() are the most meaningful cases. The third one could be avoided just by renaming the class member variable, but there's no way around using this in the first two cases.
Another possible use case of this:
#include <iostream>
using namespace std;
class A
{
public:
void foo()
{
cout << "foo() of A\n";
}
};
class B : A
{
public:
void foo()
{
((A *)this)->foo(); // Same as A::foo();
cout << "foo() of B\n";
}
};
int main()
{
B b;
b.foo();
return 0;
}
g++ this.cpp -o this
./this
foo() of A
foo() of B
One more use of this is to prevent crashes if a method is called on a method is called on a NULL pointer (similar to the NULL object pattern):
class Foo
{
public:
void Fn()
{
if (!this)
return;
...
}
};
...
void UseFoo(Foo* something)
{
something->Fn(); // will not crash if Foo == NULL
}
If this is useful or not depends on the context, but I've seen it occasionally and used it myself, too.
self-assignment protection