Один способ сделать то же самое с разными переменными - PullRequest
0 голосов
/ 11 апреля 2011

у меня что-то подобное

class Foo {
    Bar a, b, c;

    void doStuffWithA();
    void doStuffWithB();
    void doStuffWithC();
}

вместо написания реализации для каждого из методов я хочу что-то вроде шаблона. Как это сделать?

Cheers, Dirk

Edit:

Мне явно нужно знать, с какой переменной я работаю (рекурсия):

class Foo {
    Bar a, b, c;
    Foo* parent;

    static void doRecursiveStuffWithA(Foo *_node) {
        if(_node->parent==NULL) {

            return;
        } else {
            doRecursiveStuffWithA(_node->parent)
        }

    }
    static void doRecursiveStuffWithB(Foo *_node) {
        if(_node->parent==NULL) {
            return;
        } else {
            doRecursiveStuffWithB(_node->parent)
        }

    }
    static void doRecursiveStuffWithC(Foo *_node) {
        if(_node->parent==NULL) {
            return;
        } else {
            doRecursiveStuffWithC(_node->parent)
        }

    }

}

Edit2:

Может быть, это лучше объясняет мою проблему:

class Foo {
public:
    int a, b, c;

}

class Bar {
public:
    void doStuffWithAOfFoo(Foo *_foo);
    void doStuffWithBOfFoo(Foo *_foo);
    void doStuffWithCOfFoo(Foo *_foo);

}

Я просто хочу, чтобы мой код был простым и не нужно было трижды реализовать doStuffWithX ...

Ответы [ 5 ]

5 голосов
/ 11 апреля 2011

Я думаю, вам нужны параметры ...

class Foo {
    Bar a, b, c;

    void doStuffWithBar(Bar x);
}

Шаблоны предназначены для работы с различными типами данных , а аргументы функций - для работы с различными переменные .

1 голос
/ 11 апреля 2011

Вы можете использовать ссылку:

class Foo {
    Bar a, b, c;

    void doStuffWithBar(Bar& what)
    {
        print(what);
        bool flag = check(what);
        if (!flag)
            doStuffWithBar(what);
    }
}

Вы можете использовать указатель на член:

class Foo {
    Bar a, b, c;
    typedef Bar (Foo::*PointerToBar);

    void doStuffWithBar(PointerToBar selector)
    {
        print(this->*selector);
        bool flag = check(this->*selector);
        if (!flag)
            doStuffWithBar(selector);
    }
}

Последнее решение более гибкое: вы можете выбрать другой объект и / или другой элемент, с которым можно продолжить рекурсию (указатели на члены неясны и используются редко; не используйте их, если вам не нужна эта гибкость):

class Foo {
    Bar a, b, c;
    Foo* next;
    typedef Bar (Foo::*PointerToBar);

    void doStuffWithBar(PointerToBar selector)
    {
        print(this->*selector);
        if (next)
            next->doStuffWithBar(selector);
    }
}
1 голос
/ 11 апреля 2011

@ У Эндрю Уайта самый простой ответ.Если вам нужна функция, которая может делать то же самое, но с различными значениями, она должна принимать аргумент.

В некоторых случаях мы законно хотим, чтобы разные методы выглядели почти одинаково, например getFirstName()setFirstName(), getLastName(), setLastName().Там использование аргументов скорее победило бы цель.

Архитектура там совершенно здорова (и действительно широко принята);единственная проблема заключается в том, чтобы все это набирать.Если вы просто хотите избежать лишней типизации, подумайте об использовании интегрированной среды разработки, которая предлагает «шаблоны кода».И Eclipse, и Visual Studio (среди прочего, безусловно) позволят вам выбрать переменную и нажать кнопку, чтобы сгенерировать метод получения и установки для этой переменной.Весь код без хлопот.

0 голосов
/ 11 апреля 2011

Код запаха - проблема дизайна? Повторение здесь создает ощущение, что Bar нужен новый метод:

void Bar::doStuff(Foo &foo);

Тогда вам нужно выяснить, что такое public, private и const.

Редактировать: Ваша правка немного меняет дело. Теперь я действительно чувствую, что есть способы улучшить ваш дизайн, например, Контейнер STL и алгоритмы.

0 голосов
/ 11 апреля 2011

Чтобы немного рассказать о решениях Эндрю, вам также может понадобиться:

void doStuffWithBar(Bar x, Bar y, Bar z);

Если у вас действительно есть BarX x, BarY y и BarZ z, то, возможно, вы захотите перегрузить функцию-член вваш класс

class Foo {
BarX x;
BarY y;
BarZ z;

void doStuffWithBar(BarX x);
void doStuffWithBar(BarY y);
void doStuffWithBar(BarZ z);
};

Возможно, вы также ищете что-то вроде этого (это самое уродливое решение, и я бы не стал его рекомендовать):

void doStuffWithBar(int n)
{
    if(n==0)
          doSomethingWithX();
    else if(n==1)
          doSomethingWithY();
    else if(n==2)
          doSomethingWithZ();
}

Редактировать:

ReturnType Bar::doStuffWithBar(ParamA a, ParamB b);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...