-2

I want to make structure where container element can give callbacks to containers, but I dont want to make it be public. How should I make it ? I'm not guaranteed, maybe I need statically give container's private functions adress to element or use somehow friend? By the way element should "see" others container's private functions.

E.g. class Cont stores class Elem. Cont has private function void callback();. Elem knows in which Cont he is, and can call callback function. No one outside Cont can use callbacks function.

Vinigas
  • 464
  • 5
  • 18

1 Answers1

1

In the Elem constructor, you could have an argument to the callback (using e.g. std::function or similar), and have the Elem class store it. Then when the callback needs to be called, just call it.

You could also create a "setter" function in Elem to set the callback.


Full example

#include <iostream>
#include <string>
#include <functional>
#include <vector>

class Elem
{
private:
    int value_;
    std::function<void(const std::string&)> callback_;

public:
    Elem(int v, std::function<void(const std::string&)> cb)
        : value_{v}, callback_{cb}
    {}

    void some_function() const
    {
        callback_("Elem with value " + std::to_string(value_));
    }
};

class Cont
{
private:
    std::vector<Elem> elements_;

    void private_function(const std::string& s)
    {
        std::cout << "In private function: " << s << '\n';
    }

public:
    void add_value(const int v)
    {
        elements_.push_back(Elem(v, std::bind(&Cont::private_function, this, std::placeholders::_1)));
    }

    std::vector<Elem>::const_iterator begin() const
    {
        return std::begin(elements_);
    }

    std::vector<Elem>::const_iterator end() const
    {
        return std::end(elements_);
    }
};

int main()
{
    Cont c;

    // Add some elements
    for (int i = 1; i <= 10; ++i)
        c.add_value(i);

    // Call callback function
    for (const auto& e : c)
        e.some_function();
}

Output:

In private function: Elem with value 1
In private function: Elem with value 2
In private function: Elem with value 3
In private function: Elem with value 4
In private function: Elem with value 5
In private function: Elem with value 6
In private function: Elem with value 7
In private function: Elem with value 8
In private function: Elem with value 9
In private function: Elem with value 10

See it in action.

In the code above, the private function Cont::private_function is totally unknown to the Elem class, and can't be called directly. However, we can pass it to the Elem class using arguments, and then call it from inside the Elem class without exposing the private function at all.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I need to store `class Cont` private function adress in `class Elem` statically and store `Cont c1` adress in `Elem e1` dinamically. How to assign `class Cont` private function's adress to `class Elem`'s static variable once when program starts ? – Vinigas Sep 22 '15 at 11:02
  • @Vinigas Added a simple example of what I mean. – Some programmer dude Sep 22 '15 at 11:22
  • @Joachim_Pileborg So callback_ gonna store specific container's adress and function to it ? What `std::placeholders::_1"` is for ? – Vinigas Sep 22 '15 at 11:43
  • @Vinigas The `std::placeholders::_1` is because the function I pass to [`std::bind`](http://en.cppreference.com/w/cpp/utility/functional/bind) takes one argument, and `std::bind` needs a placeholder where that argument should be. – Some programmer dude Sep 22 '15 at 11:49
  • @Vinigas And exactly what `std::bind` returns, or `std::function` stores doesn't matter, all that's matter is that by "calling" `callback_` in the `Elem` class you call the function passed to the `std::bind` call. – Some programmer dude Sep 22 '15 at 11:50