Метод класса для вызова метода переменной - PullRequest
0 голосов
/ 27 ноября 2018

Моя текущая ситуация имеет такую ​​структуру:

class Foo {
    public:
        void call() {
            b.call();
        }
    private:
        Bar b;
};

class Bar {
    public:
        void call() {
            std::cout << "Hello there" << std::endl;
        }
};

int main() {
    Foo f;

    f.call(); // This calls directly the b.call() function
}

Существует ли синтаксис, который мог бы напрямую вызывать функцию Foo.call для вызова функции внутри класса, хранящейся в виде переменной?

По сути, есть ли синтаксис, который может сделать что-то вроде:

class Foo {
    public:
        void call() -> b.call
    private:
        Bar b;
};

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Обычно нет необходимости пытаться помочь такому компилятору.Компиляторы очень хороши в оптимизации такого рода вещей.Вам не нужно указывать компилятору Foo::call на самом деле просто Bar::call.Компилятор это выяснит.Рассмотрим слегка подправленный пример:

extern void DisplayMessage(char const*);

class Bar {
public:
  void call() {
    DisplayMessage("Hello there");
  }
};

class Foo {
public:
  void call() {
    b.call();
  }
private:
  Bar b;
};

int main() {
  Foo f;

  f.call(); // This calls directly the b.call() function
}

Когда я компилирую это с использованием Clang 7.0 и -O3, я получаю следующее:

main:                                   # @main
    push    rax
    mov     edi, offset .L.str
    call    DisplayMessage(char const*)
    xor     eax, eax
    pop     rcx
    ret

Обратите внимание, что компилятор полностью удалил объекты иоставил только прямой вызов функции DisplayMessage.

0 голосов
/ 27 ноября 2018

Код может быть короче:

class Bar {
public:
    void call() const {
        std::cout << "Hello there" << std::endl;
    }
};

class Foo : private Bar // private is superfluous here, as we use class instead of struct
{
public:
    using Bar::call;
};

, но способ компоновки с ручной пересылкой кажется более естественным.

0 голосов
/ 27 ноября 2018

Вы говорите о конструкции делегата уровня языка.Некоторые языки имеют встроенную поддержку для этого, но C ++ нет.Вы должны сделать это «трудным путем», как у вас.

Если это действительно распространенная вещь, вы можете определить макрос, но обычно лучше иметь некрасивый код, чем запутывающий или вводящий в заблуждение код.

...