C ++ const перегрузка и совместное использование кода - PullRequest
2 голосов
/ 06 октября 2011

У меня есть класс, у которого есть метод-член f и g, оба перегружены const.Есть вызовы g () внутри f ().Тело метода для f и const f одно и то же.

class X {
 void f() {/body ... g() /} const;
 void f() {/body g() /};

 void g() const;
 void g();
};

Поскольку f () и g () имеют одинаковое тело метода, я действительно хотел бы иметь один метод, а не копировать дублирующийся кодмежду f и const f.

Более того, когда тело функции f () выполняется для объекта const, я хочу, чтобы выполнялась очевидная функция const g () (и неконстантная g () для неконстантных объектов).).

Ответы [ 5 ]

1 голос
/ 06 октября 2011

С другой точки зрения, у вас не будет дублированного кода, так как в ваших f() вызываются не одинаковые g().Что вы можете сделать, это разбить код в F:

class X {
 void body() {};
 void f() {body(); g() } const;
 void f() {body(); g() };

 void g() const;
 void g();
};
1 голос
/ 06 октября 2011

Я не верю, что это можно сделать с помощью функций-членов шаблона (но я легко могу ошибаться); поэтому наилучшим вариантом может быть выделение общего кода в другой метод.

class X {
    void g() const;
    void g();

    void body() const { ... }

    void f() const { body(); g(); }
    void f() { body(); g(); }
}; 
0 голосов
/ 07 октября 2011

Вы можете реализовать f в шаблонной функции, которая передается (X*)this или (const X*)this.

#include <cstdio>

class X {
    void g() const { std::puts("const"); }
    void g() { std::puts("non-const"); }

    void body() const { }

public:
    void f() const { f_impl(this); }
    void f() { f_impl(this); }

private:
    template <class Self>
    static void f_impl(Self* self)
    {
        self->body();
        self->g(); 
    }
}; 

int main()
{
   X x;
   x.f();
   const X y = {};
   y.f();
}

(Возможно, не очень приятно реализовывать большие функции в заголовках, хотя.)

0 голосов
/ 06 октября 2011
class X {
 void f_impl() const { /body }
 void f() {f_impl(); ... g(); /} const;
 void f() {f_impl(); g(); /};

 void g() const;
 void g();
};
0 голосов
/ 06 октября 2011

Можете ли вы сделать это:

class X {
 void body(){/body ... /} const;
 void f() {body(); g(); } const;
 void f() {body(); g(); };

 void g() const;
 void g();
};

Если вы не можете, это потому, что / body ... / имеет постоянную и неконстантную версию?

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

Некоторые идеи:

  1. Сделать тело макросом
  2. Поместить тело в body.inc и # включить его в методы (излишнее уничтожение)
...