magu_
magu_

Reputation: 4856

typedef with function pointer

I want to transfer a function pointer in the constructor but get some error Messages...

I my parent class I declared:

class Strip{

public:
     typedef void(Strip::*LOG)(const std::string&);

with a function log(const string&)

In my child class I forward declare Strip with class Strip and have somthing like that

class Observable{

public:

  Observable(const char &signal,Strip::LOG log,const QCustomPlot *plot);

with a parameter

Strip::LOG log;

When I try to compile I get the error's

Strip::LOG has not been declared and LOG in class Strip does not name a type

Any Idea how to fix that?

Upvotes: 1

Views: 315

Answers (2)

Mgetz
Mgetz

Reputation: 5128

So passing a pointer to a member function presents several issues:

  1. It's a member function as such it will need to have an instance of the class passed into it to work (the implicit this parameter).
  2. It doesn't prevent the class you're passing it to from knowing about the class the function pointer originates so you gain nothing in terms of hiding.

A better way is to declare an Interface and pass that

// ILogger.hpp
// should be completely virtual
struct ILogger{
    virtual void log(const ::std::string&) = 0;
};

// Strip.cpp
class Strip : public ILogger{
public:
    void log(const ::std::string& data){
        // does something
    }
};


// Observable.cpp
#include "ILogger.hpp"
class Observable{
public:
    Observable(ILogger* logger);
};


// some other file that knows about and constructs both

// has to be a pointer allocated to new to make the Vtables work
::std::unique_ptr<Strip> s(new Strip());

// pass in the pointer to an instance of a class that implements ILogger
Observable observed(s.get());

Using an interface means you can completely abstract the two classes apart and Observable need not know anything about the instance being passed to it other than it implements ILogger. Internally Observable can call the logger by just calling logger->log.

Upvotes: 1

αλεχολυτ
αλεχολυτ

Reputation: 5039

May be this code can be usefull (compiled w/o errors):

#include <iostream>
using namespace std;

class Strip{
public:
    typedef void(Strip::*LOG)(const std::string&);
    void log(const string& s)
    {
        cout << "log() called\n";
    }     
};

class Observable{
public:
    Observable( Strip::LOG l )
    {
        Strip s; 
        (s.*l)("string");
    }
};

int main() {
    Strip::LOG log = &Strip::log;
    Observable o( log );
    return 0;
}

http://ideone.com/RD4K1r

Upvotes: 0

Related Questions