Решение
Создайте файл .inl и с помощью #includeвключите его в конец своего заголовочного файла. Это эквивалентно помещению определения функции в конец заголовочного файла, но позволяет хранить объявление и определение раздельно. Пример 2.6 показывает, как это делается.
Пример 2.6. Использование встраиваемого файла
// Value.h
#ifndef VALUE_H__
#define VALUE_H__
#include
class Value {
public:
Value (const std::string& val) : val_(val) {}
std::string getVal() const;
private:
std::string val_;
};
#include "Value.inl"
#endif VALUE_H__
// Value.inl
inline std::string Value::getVal() const {
return(val_);
}
Это решение не требует пояснений, #includeзаменяется на содержимое ее аргумента, так что здесь в заголовочный файл включается содержимое Value.inl . Следовательно, любой файл, включающий этот заголовочный файл, содержит определения встраиваемых функций, но вам не требуется загромождать объявление класса.
Даже если вы не занимаетесь написанием научных или инженерных приложений, вам все равно придется работать с числами. Эта глава содержит решения проблем, часто возникающих при работе с числовыми типами С++.
Некоторые из рецептов содержат методики преобразования из числовых типов в тип stringи обратно чисел, представленных в различных форматах (шестнадцатеричном, с плавающей точкой или экспоненциальном). Самостоятельное написание кода для таких преобразований утомительно и требует времени, так что я показываю возможности стандартной библиотеки или одной из библиотек Boost, облегчающие выполнение этих задач. Также имеется несколько рецептов по работе исключительно с числовыми типами: безопасное преобразование между ними, сравнение чисел с плавающей точкой с граничными значениями и поиск минимального и максимального значений.
Рецепты в этой главе предоставляют решения некоторых общих проблем, с которыми обычно сталкиваются при работе с числами в С++, но они не пытаются решать проблем, специфичных для конкретных приложений. При написании научного или инженерного приложения вам также следует взглянуть на главу 11, которая содержит рецепты ко многим общим научным и инженерным алгоритмам.
3.1. Преобразование строки в числовой тип
Проблема
Имеются числа в строковом формате, и вам требуется преобразовать их в числовой тип, такой как intили float.
Решение
Это можно сделать двумя способами — с помощью функций стандартной библиотеки или с помощью класса lexical_castиз Boost (написанного Кевлином Хенни (Kevlin Henney) Функции стандартной библиотеки неуклюжи и небезопасны, но они стандартны, и в некоторых случаях потребуются именно они, так что в первом решении я представлю именно их. lexical_castболее безопасен, проще в использовании и интереснее, так что я представляю его в обсуждении.
Функции strtol, strtodи strtoul, определенные в , преобразуют символьные строки, ограниченные нулем, в long int, doubleили unsigned long. Они могут использоваться для преобразования чисел, представленных в виде строк с любым основанием, в числовые типы. Код примера 3.1 демонстрирует функцию hex2int, которая предназначена для преобразования шестнадцатиричной строки в long.
Пример 3.1. Преобразование числовых строк в числа
#include
#include
#include
using namespace std;
long hex2int(const string& hexStr) {
char *offset;
if (hexStr.length( ) > 2) {
if (hexStr[0] == '0' && hexStr[1] == 'x') {
return strtol(hexStr.c_str(), &offset, 0);
}
}
return strtol(hexStr.c_str( ), &offset, 16);
}
int main() {
string str1 = "0x12AB";
cout << hex2int(str1) << endl;
string str2 = "12AB";
cout << hex2int(str2) << endl;
string str3 = "0AFG";
cout << hex2int(str3) << endl;
}
Вот вывод этой программы.
4779
4779
0
Первые две строки содержат шестнадцатеричное число 12AB. Первая из них содержит префикс 0x, а вторая — нет. Третья строка не содержит правильного шестнадцатеричного числа. В этом случае функция просто возвращает 0.
Обсуждение
Некоторые люди склонны писать свои собственные функции для преобразования шестнадцатеричных чисел в целочисленные форматы. Но зачем изобретать колесо? Стандартная библиотека уже предоставляет эту функциональность. Пример 3.1 представляет собой функцию-оболочку, упрощающую вызов strtol. Функция strtol— это старая функция библиотеки С, и она требует от вас передачи указателя на завершающуюся нулем строку, а так же адрес еще одного указателя на строку. Этот второй указатель получает адрес, на котором обработка строки завершилась. Однако в C++ большинство людей предпочитает работать с более мощным классом string, а не со старыми указателями на символьные строки. Поэтому функция hex2intпринимает параметр типа string.
Читать дальше