Defining Class Functions for later

Hey guys,

I'm curious if there is a way to define a function name, but not it's function.

As in:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class WindowPane {
    private: 
      int ax,ay,w,h;
    public:
      WindowPane {}
      ~WindowPane {}

    void KeyCommand(...);
}

// Then in another file

  WindowPane MyPain();
  WindowPane MyRealPain();

  MyPain.KeyCommand(char kbStroke) {
    // does stuff here
  }

  MyRealPain.KeyCommand(string message) {
     // does stuff here
  }


Thank you in advance.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

struct A // (in a header file, say a.h)
{
    int value() const ; // declare the member function in the class

    private: int v = 22 ;
};

int main() // (in some implementation file, say main.cpp)
{
    A a ;
    std::cout << a.value() << '\n' ;
}

// define the member function (in an implementation file, say a.cpp)
int A::value() const { return v ; }
You can declare a function and define it later. However, you're defining it incorrectly.
1
2
3
4
5
6
7
8
9
10
// incorrect
MyPain.KeyCommand(char kbStroke) {
    // does stuff here
}

// correct
void WindowPane::KeyCommand(char kbStroke)
{
    // does stuff here
}
Last edited on
The sample you posted doesn't make any sense to me, and I don't know what you by "defining a function name, but not its function".

What you've posted, sort of looks like function overloading:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class WindowPane {
    //...
    public:
    //...
    void KeyCommand(char kbStroke);
    void KeyCommand(string message);
}

//...

void WindowPane::KeyCommand(char kbStroke){
    //...
}

void WindowPane::KeyCommand(string message){
    //...
}
But you can't declare WindowPane::KeyCommand() as just taking whatever and then define specific types for the parameters in another file. It just doesn't work that way.

If the different overloads all have more or less the same "shape" you can use a template function:
1
2
3
4
5
6
7
8
9
class WindowPane {
    //...
    public:
    //...
    template <typename T>
    void KeyCommand(T whatever){
        std::cout << whatever << std::endl;
    }
}
I was wanting to start out with a default class I can reuse on different projects and then redefine/write each function for each declaration. As in, define what all of them are able to do, and then add more to it.

But I guess it may be better to have:
class WindowPane : public MenuPane : public InfoPane : public EditPane ... etc
Last edited on
I'm not wanting to hard code everything

Usually "hard coded" refers to (especially) data that is compiled into a binary and not easily changed. Do you need user-programmable behavior?

If you know all the desired behaviors at compile-time you can simply pass behaviors around as closures, in whatever order you like. C++ has library and core language support for higher-order programming.

The separation of key-behavior from each window/pane/buffer/whatever is a relatively basic idea... it most-likely doesn't require anything more sophisticated. Why is some collection (hashtable?) of KeyCommand objects not sufficient?
Last edited on
I think the easiest way to do that would be
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Base{
public:
    virtual void foo(Object &){
        // Do nothing.
    }
};

class Derived1 : public Base{
public:
    void foo(Object &) override;
}

class Derived2 : public Base{
public:
    void foo(Object &) override;
}

class Derived3 : public Base{
public:
    void foo(Object &) override;
}

//...

void Derived1::foo(Object &obj){
    auto p = dynamic_cast<Char *>(&obj);
    if (!p)
        return;
    // Do something useful.
}

void Derived2::foo(Object &obj){
    auto p = dynamic_cast<String *>(&obj);
    if (!p)
        return;
    // Do something useful.
}

void Derived3::foo(Object &obj){
    auto p1 = dynamic_cast<Char *>(&obj);
    if (!p1){
        auto p2 = dynamic_cast<String *>(&obj);
        if (!p2)
            return;
        // Do something useful.
    }else{
        // Do something useful.
    }
}
> I was wanting to start out with a default class I can reuse on different projects and then
> redefine/write each function for each declaration.
> As in, define what all of them are able to do, and then add more to it.

>> If you know all the desired behaviors at compile-time you can simply pass behaviors around as closures,
>> in whatever order you like. C++ has library and core language support for higher-order programming.
>> Why is some collection (hashtable?) of KeyCommand objects not sufficient?

Yes, mbozzi's idea is sound, and should probably take care of the problem.

However, if this is very important: 'class I can reuse on different projects' and there are many classes with complex interactions between them, introducing an additional layer of abstraction that encapsulates this complexity would be very flexible.

The mediator pattern - "Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently".
https://sourcemaking.com/design_patterns/mediator
http://www.oodesign.com/mediator-pattern.html

Then we can have a concrete implementation of the mediator for each program (or for each interaction scenario within a program).
Each feature I write these days, I want to push myself to use something new (to me), to push myself out of my comfort zone to be better than just sticking to the if/for/while/switches I'm use to.

JLBorges, Great advice, I'll look into those. Thank you

MBozzi, Hashtable ... I need to learn what that is, and how to use it. Thank you
- The thought is a long term one, I want to have some core code (maybe my own name space) that helps at the start of all new projects, like text code that already includes Ctlr-Z for undo, and Esc always breaks you out of what ever you are in, and the like.
From there I'll build more onto it as needed for each project. Although, I'm highly guilty for making things more complex than I should.

Helios, I don't know why that didn't come to me, but virtual functions, that might have been what I was trying to recall. Thank you

I guess today will be a day of notes and research. Great advice, thank you all!

Topic archived. No new replies allowed.