Предоставление реализации функции более чем одному имени в c ++ - PullRequest
5 голосов
/ 14 ноября 2010

Допустим, у меня есть базовый класс 2D-векторов, например,

class vector2
{
  int x, y;
}

. Эти два значения могут использоваться для представления позиции, а также ширины и высоты.С ++ предоставляет мне возможность использовать такую ​​функцию, как vector2::getXpos(), а затем определить vector2::getWidth() и использовать ее в одной и той же реализации.

Я знаю, что я мог бы просто сделать обе эти функции встроенными,но компилятор может решить не включать эти функции.так что если бы getWidth только что вызвал getXpos, вы бы в итоге получили два вызова функций.

Более надежный пример того, для чего я хотел бы использовать это: getLength() и erm ... getSpan()(думая как экран, когда вы говорите 40 "телевизор)

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

РЕДАКТИРОВАТЬ

Я не спрашиваю о механикевстроенных функций ... Я в основном хочу сделать что-то функционально, например

class MyClass
{
  void ActaullyDoStuff();
  public:
  void foo(){ActaullyDoStuff();}
  void bar(){ActuallyDoStuff();}
}

, но где я могу просто написать что-то вроде

class MyBetterClass
{
  public:
  void foo(){ /* BLOCK OF CODE */ }
  void bar(){ /* DO WHAT EVER foo() DOES */ }
}

Я хочу, чтобы bar() был другим способомпросто foo(), чтобы один и тот же функциональный код мог иметь разные, более подходящие имена в зависимости от ситуации.

Ответы [ 6 ]

4 голосов
/ 14 ноября 2010

но компилятор может решить не включать эти функции

Тогда у компилятора, вероятно, есть веская причина для этого.

Я думаю, что это не проблемапросто сделайте так, чтобы функция с альтернативным именем вызывала «настоящую» функцию, и компилятор, скорее всего, ее встроит.

РЕДАКТИРОВАТЬ:

Если это не убедило вас, это возможноиспользовать __ forceinline в visual studio. Здесь - это способ принудительного использования inline в GCC.

EDIT2:

class MyBetterClass
{
  public:
  void foo(){ /* BLOCK OF CODE */ }
  __forceinline void bar(){ foo(); /* DO WHAT EVER foo() DOES */ }
}
1 голос
/ 01 марта 2015

Используя C ++ 11, вы можете сделать:

//works for non-template non-overloaded functions:

const auto& new_fn_name = old_fn_name;

Другие решения: Как назначить псевдоним имени функции в C ++?

1 голос
/ 14 ноября 2010

Похоже, вы не думаете об этом объектно-ориентированным способом. У меня второй совет mjfgates, что вы действительно не хотите этого делать.

То, что вы хотите сделать, это абстрагировать идею вектора в класс и реализовать общие методы, которые вы, возможно, захотите использовать с вектором. Фактически, вы можете рассмотреть возможность реализации приведенного выше примера класса как класса «Point», а затем иметь класс «Vector», объединяющий два класса точек.

Используя ваш пример, ваш класс не был бы хорошо определен, если бы он использовался для двух разных целей. Допустим, вы хотите создать метод для некоторого класса для рисования vector2. Вы должны знать, какие экземпляры vector2 представляют начальную точку, а какие представляют ширину / высоту. Вам, вероятно, также понадобится третье представление для представления направления. Более простой способ - реализовать вектор в терминах getStartPoint, getEndPoint и любых других методов, которые будут выполнять вычисления, подходящие для вектора. Тогда потребителю не нужно знать о внутренней работе класса vector2, он просто вызывает методы для получения необходимой информации.

1 голос
/ 14 ноября 2010

Ссылка, на которую вы ссылаетесь, - это AFAIK, также не функция C, но что-то специфическое для этого конкретного компилятора.

C ++ предоставляет такой механизм: это встроенные функции! Беспокоиться о том, что компилятор не оптимизирует избыточный вызов встроенной функции, безусловно, преждевременная оптимизация. Встроенный, а затем измерить, если вы беспокоитесь о производительности.

Если вы абсолютно настаиваете на исключении простейшего шанса избыточного вызова, вы можете сделать что-то с препроцессором #define s ... но будьте осторожны: макросы не учитывают границы классов, и ваши заголовочные файлы рано или поздно будут топать какой-то другой, не связанный код. Лучше не ходи туда.

0 голосов
/ 14 ноября 2010

вы можете использовать препроцессор #define s .... если вы в худших ошибках в мире.Вы получите эквивалент гарантированного встроенного, если хотите, или просто псевдонимы, если вы тоже этого захотите.

0 голосов
/ 14 ноября 2010

Итак, вы хотите иметь две функции на одном объекте, которые возвращают точно такие же данные, что и один и тот же тип данных.

Не делай этого.

Предоставление более чем одного пути к одним и тем же данным - одна из тех вещей, которая может показаться удобной для тех, кто собирается использовать ваш объект - до тех пор, пока вы не подумаете об этом. Происходит то, что через шесть месяцев кто-то обнаруживает ошибку в одной из двух функций, и вы исправляете эту функцию, но не другую, так что ошибка все еще существует. Или программисту, который пишет клиенты для вашего объекта, безумно интересно, в чем разница между getLength () и getSpan ().

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

...