Каковы Ваши любимые [закрытые] идиомы Стиля кодирования C++

Это происходит, когда вы пытаетесь получить доступ к ресурсам другого домена.

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

Заголовок ответа, даже если он 200OK не позволяет другим источникам (доменам, портам) обращаться к ресурсам ressources.

Вы можете исправить эта проблема, если вы являетесь владельцем обоих доменов:

Решение 1: через .htaccess

Чтобы изменить это, вы можете записать это в .htaccess запрошенного файла домена:

    <IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
    </IfModule>

Решение 2: установите заголовки правильным способом

Если вы установите это в заголовок ответа запрошенного файла, вы разрешите всем получить доступ к ресурсам ressources:

Access-Control-Allow-Origin : *

ИЛИ

Access-Control-Allow-Origin : http://www.my-domain.com

Мир и код;)

60
задан 2 revs, 2 users 100% 9 November 2008 в 17:37
поделиться

22 ответа

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

namespace EntityType {
    enum Enum {
        Ground = 0,
        Human,
        Aerial,
        Total
    };
}

void foo(EntityType::Enum entityType)
{
    if (entityType == EntityType::Ground) {
        /*code*/
    }
}

РЕДАКТИРОВАНИЕ : Однако эта техника стала устаревшей в C++ 11. Ограниченное по объему перечисление (объявленный с enum class или enum struct) должно использоваться вместо этого: это более безопасно с точки зрения типов, кратко, и гибко. С перечислениями старого стиля значения помещаются во внешний объем. С модернизированным перечислением они размещаются в рамках эти enum class имя.
Предыдущий пример, переписанный с помощью ограниченного по объему перечисления (также известный как перечисление со строгим контролем типов ):

enum class EntityType {
    Ground = 0,
    Human,
    Aerial,
    Total
};

void foo(EntityType entityType)
{
    if (entityType == EntityType::Ground) {
        /*code*/
    }
}

существуют другие значительные преимущества от использования ограниченных по объему перечислений: отсутствие неявного броска, возможного предописания и способности использовать пользовательский базовый тип (не значение по умолчанию int).

59
ответ дан 3 revs, 2 users 63% 7 November 2019 в 13:53
поделиться

Я склонен еще помещать на всю свою IFS.

if (condition)
{
    complicated code goes here
}
else
{
    /* This is a comment as to why the else path isn't significant */ 
}

Даже при том, что это раздражает моих коллег. Можно сказать сразу, что я еще рассмотрел случай во время кодирования.

-1
ответ дан EvilTeach 7 November 2019 в 13:53
поделиться

Я обычно придерживаюсь KNF, описанной в *СТИЛЬ BSD (9)

0
ответ дан Terminus 7 November 2019 в 13:53
поделиться

Я всегда придираюсь к мелочам и редактирую следующее:

  • Лишние новые строки
  • Никакая новая строка в EOF
0
ответ дан korona 7 November 2019 в 13:53
поделиться

Зарегистрируйте возвращаемые значения на функциональной строке, таким образом, их очень легко найти.

int function(void) /* return 1 on success, 0 on failure */ 
{
    return 1;
};
2
ответ дан 2 revs 7 November 2019 в 13:53
поделиться

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

int ReturnMaxValue(
    int* inputList,   /* the list of integer values from which to get the maximum */
    long size,        /* count of the number of integer values in inputList */
    char* extraArgs   /* additional arguments that a caller can provide.    */
)
1
ответ дан Ather 7 November 2019 в 13:53
поделиться

Полезно поставить имена функций в новой строке, таким образом, Вы можете grep как

grep -R '^fun_name' .

для них. Я видел, что стиль использовал для загрузки проектов GNU и как он:

static void
fun_name (int a, int b) {
    /* ... */
}
2
ответ дан Johannes Schaub - litb 7 November 2019 в 13:53
поделиться

Не уверенный, если это рассчитывает как идиома, но я склонен использовать doxygen - стиль встроенные комментарии, даже когда проект не - еще использующий doxygen...

bool MyObjects::isUpToSomething() ///< Is my object up to something 

(в стороне. моими комментариями не является обычно вполне тот Ламе.)

3
ответ дан 2 revs, 2 users 93% 7 November 2019 в 13:53
поделиться

Мне действительно нравится помещать маленький оператор на ту же строку как если

int myFunc(int x) {
   if(x >20) return -1;
   //do other stuff ....
}
4
ответ дан 2 revs, 2 users 93% 7 November 2019 в 13:53
поделиться

ре: ididak

я фиксирую код, который повреждает длинные операторы в слишком много коротких строк.

Позволяют нам столкнуться с ним: это больше не 90-е. Если Ваша компания не может позволить себе широкоэкранный LCDs для своих кодеров, необходимо получить лучшее задание:)

7
ответ дан Buddy 7 November 2019 в 13:53
поделиться

Никакое избранное, но я буду фиксировать код, который имеет:

  1. вкладки - вызывают неточное совмещение во многих IDE и инструментах обзора кода, потому что они не всегда договариваются о вкладке в модификации 8 пробелов.
  2. строки дольше, чем 80 столбцов - позволяют нам столкнуться с ним, более короткие строки более читаемы. Мой мозг может проанализировать большинство соглашений кодирования, пока строки коротки.
  3. строки с запаздывающими пробелами - мерзавец будет жаловаться на это как пробел ошибки , которые обнаруживаются как красные блобы в diffs, который является раздражающим.

Вот острота для нахождения незаконных файлов:

git grep -I -E '<tab>|.{81,}|  * 

, где <tab> символ табуляции (POSIX regexp не делает \t)

| cut -f1 -d: | sort -u

, где <tab> символ табуляции (POSIX regexp не делает \t)

7
ответ дан ididak 7 November 2019 в 13:53
поделиться

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

void foo( int a, int b )
{
  int c = a + ( a * ( a * b ) );
  if ( c > 12 )
    c += 9;
  return foo( 2, c );
}
4
ответ дан 2 revs 7 November 2019 в 13:53
поделиться

В if операторы, когда существуют трудные условия, можно ясно показать, какой уровень каждое условие использует добавление отступа.

if (  (  (var1A == var2A)
      || (var1B == var2B))
   && (  (var1C == var2C)
      || (var1D == var2D)))
{
   // do something
}
11
ответ дан 3 revs, 2 users 69% 7 November 2019 в 13:53
поделиться

Мне нравится выстраивать в линию код/инициализации в 'столбцах'... Оказывается очень полезным при редактировании с режимом 'столбца' способного редактора и также, кажется, намного легче для меня читать...

int myVar        = 1;    // comment 1
int myLongerVar  = 200;  // comment 2

MyStruct arrayOfMyStruct[] = 
{   
    // Name,                 timeout,   valid
    {"A string",             1000,      true    },   // Comment 1
    {"Another string",       2000,      false   },   // Comment 2 
    {"Yet another string",   11111000,  false   },   // Comment 3
    {NULL,                   5,         true    },   // Comment 4
};

Напротив, тот же код, не расположенный с отступом и отформатированный как выше, появился бы... (Немного тяжелее для чтения в мои глаза)

int myVar = 1; // comment 1
int myLongerVar = 200; // comment 2

MyStruct arrayOfMyStruct[] = 
{   
    // Name, timeout, valid
    {"A string", 1000, true},// Comment 1
    {"Another string", 2000, false }, // Comment 2 
    {"Yet another string", 11111000,false}, // Comment 3
    {NULL, 5, true }, // Comment 4
};
22
ответ дан Prembo 7 November 2019 в 13:53
поделиться

Шаблон и крючок

Это способ обработать как можно больше в структуре и дать дверь или крючок для настройки с помощью пользователи фреймворка. Также известен как Hotspot и Template Method .

class Class {
  void PrintInvoice();     // Called Template (boilerplate) which uses CalcRate()
  virtual void CalcRate() = 0;  // Called Hook
}

class SubClass : public Class {
  virtual void CalcRate();      // Customized method
}

Описан Вольфгангом Пре в его книге Шаблоны проектирования для разработки объектно-ориентированного программного обеспечения .

5
ответ дан 24 November 2019 в 17:26
поделиться

RAII: получение ресурсов - это инициализация

RAII может быть самой важной идиомой. Идея заключается в том, что ресурсы должны быть сопоставлены с объектами, чтобы время их жизни управлялось автоматически в соответствии с областью, в которой эти объекты объявлены.

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

Одним из основных преимуществ этого является то, что C ++ гарантирует, что деструкторы вызываются, когда объект выходит за пределы области , независимо от того, как контроль покидает эту область . Даже если возникнет исключение, все локальные объекты выйдут из области видимости, и связанные с ними ресурсы будут очищены.

void foo() {
  std::fstream file("bar.txt"); // open a file "bar.txt"
  if (rand() % 2) {
    // if this exception is thrown, we leave the function, and so
    // file's destructor is called, which closes the file handle.
    throw std::exception();
  }
  // if the exception is not called, we leave the function normally, and so
  // again, file's destructor is called, which closes the file handle.
}

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

RAII также менее известен как SBRM (Scope-Bound Resource Management).

См. Также:

  • ScopeGuard позволяет коду «автоматически вызывать операцию отмены .. в случае возникновения исключения».
65
ответ дан 24 November 2019 в 17:26
поделиться

Компилирующий временной полиморфизм

(Также известный как синтаксический полиморфизм и статический полиморфизм, в отличие от runtime polymorphism)

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

В книге Elements of Programming авторы называют данную трактовку типов абстрактными родами . С помощью понятий можно уточнить требования к параметрам такого типа, хотя С++ не предписывает таких спецификаций.

Два простых примера:

#include <stdexcept>

template <typename T>
T twice(T n) {
  return 2 * n;
}

InIt find(InIt f, InIt l,
          typename std::iterator_traits<InIt>::reference v)
{
  while (f != l && *f != v)
    ++f;
  return f;
}   

int main(int argc, char* argv[]) {
  if (6 != twice(3))
    throw std::logic_error("3 x 2 = 6");

  int const nums[] = { 1, 2, 3 };
  if (nums + 4 != find(nums, nums + 4, 42))
    throw std::logic_error("42 should not have been found.");

  return 0;
}

Можно вызвать дважды с любым регулярным типом, для которого определен двоичный оператор *. Аналогично, можно вызвать find() с любыми типами, которые являются сопоставимыми, и модель Input Iterator. Один набор кода одинаково работает с разными типами, при этом не видно общих базовых классов.

Конечно, здесь происходит то, что один и тот же исходный код, будучи расширенным на различные типы-специфические функции во время инстанцирования шаблона, каждая из которых имеет отдельный генерируемый машинный код. Размещение одного и того же набора типов без шаблонов потребовало бы либо 1) отдельных рукописных функций со специфическими сигнатурами, либо 2) полиморфизма во время исполнения через виртуальные функции.

7
ответ дан 24 November 2019 в 17:26
поделиться

Я бы посоветовал PIMPL или, как первоначально назвал его Джеймс Коплиен, «Тело ручки».

Эта идиома позволяет полностью отделить интерфейс от реализации. При работе над переписыванием и повторным выпуском основного компонента промежуточного программного обеспечения CORBA эта идиома использовалась для полного отделения API от реализации.

Это практически исключило любую возможность обратного проектирования.

Отличным источником идиом C ++ является превосходная книга Джеймса Коплиена « Advanced C ++ Programming Styles and Idioms ». Настоятельно рекомендуется!

Редактировать: Как указано ниже Нилом, эта книга довольно устарела, и многие из его рекомендаций фактически включены в сам стандарт C ++. Тем не менее, я по-прежнему считаю, что это источник полезной информации, особенно. в виде его статьи PLoP по идиомам C ++ , в которой многие идиомы были преобразованы в форму шаблонов.

1
ответ дан 24 November 2019 в 17:26
поделиться

pImpl: указатель на реализацию

Идиома pImpl - очень полезный способ отделить интерфейс класса от его реализации.

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

Заголовок windows.h является ярким примером здесь. Мы можем захотеть обернуть HANDLE или другой тип Win32 внутри класса, но мы не можем поместить HANDLE в определение класса без включения windows.h везде используется класс.

Тогда решение состоит в том, чтобы создать P частную IMPL обработку или P ointer to- IMPL расширение класса, и пусть публичная реализация хранит только указатель на частную и пересылает все методы-члены.

Например:

class private_foo; // a forward declaration a pointer may be used

// foo.h
class foo {
public:
  foo();
  ~foo();
  void bar();
private:
  private_foo* pImpl;
};

// foo.cpp
#include whichever header defines the types T and U

// define the private implementation class
class private_foo {
public:
  void bar() { /*...*/ }

private:
  T member1;
  U member2;
};

// fill in the public interface function definitions:
foo::foo() : pImpl(new private_foo()) {}
foo::~foo() { delete pImpl; }
void foo::bar() { pImpl->bar(); }

Реализация foo теперь отделена от его открытого интерфейса, так что

  • он может использовать элементы и типы из других заголовков, не требуя наличия этих зависимостей, когда class, и
  • реализация может быть изменена без принудительной перекомпиляции кода, который использует класс.

Пользователи класса просто включают заголовок, который не содержит ничего конкретного о реализации класса. Все детали реализации содержатся внутри foo.cpp .

27
ответ дан 24 November 2019 в 17:26
поделиться

Я бы рекомендовал вам пройти через PEP 8 , который является «официальным» руководством по стилю Python для кода Python. Он охватывает (среди прочего) использование вкладок/пробелов.

-121--2070633-

Для стиля Python выполните команду PEP 8 . В PEP 8 говорится: Отступы

Используйте 4 места на уровень отступа.

Для действительно старого кода, который вы не хотите испортить, вы можете продолжить для использования 8-пространственных вкладок.

Вкладки или места?

Никогда не смешивайте вкладки и места.

Наиболее популярным способом отступа Python является использование только мест. второй по популярности способ - только с вкладками. Код с отступом смесь вкладок и мест следует преобразовать в использование мест исключительно. При вызове интерпретатора командной строки Python с параметр -t выдает предупреждения о коде, который незаконно смешивает вкладки и мест. При использовании -tt эти предупреждения становятся ошибками. Они варианты настоятельно рекомендуются!

-121--2070630-

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

4
ответ дан 24 November 2019 в 17:26
поделиться

COPY-SWAP

SWAP COPE-SWAP обеспечивает безопасное копирование исключения. Это требует, чтобы правильный CTOR CTOR и SWAP реализован.

struct String {
  String(String const& other);

  String& operator=(String copy) { // passed by value
    copy.swap(*this); // nothrow swap
    return *this; // old resources now in copy, released in its dtor
  }

  void swap(String& other) throw() {
    using std::swap; // enable ADL, defaulting to std::swap
    swap(data_members, other.data_members);
  }

private:
  Various data_members;
};
void swap(String& a, String& b) { // provide non-member for ADL
  a.swap(b);
}

Вы также можете реализовать метод подкачки с помощью ADL (зависимый от Argance Lookep) .

Эта идиома важна, потому что он обрабатывает самостоятельное задание [1], делает сильное исключение гарантию [2] и часто очень легко написать.


[1] Несмотря на то, что самостоятельное задание не обрабатывается как можно более эффективно, он должен быть редким , поэтому, если он никогда не бывает, это на самом деле быстрее.

[2] Если какое-либо исключение брошено, состояние объекта ( * это ) не изменяется.

37
ответ дан 24 November 2019 в 17:26
поделиться

CRTP: Любопытно повторяющаяся шаблон шаблона

CRTP происходит при прохождении класса в качестве параметра шаблона в свой базовый класс:

template<class Derived>
struct BaseCRTP {};

struct Example : BaseCRTP<Example> {};

в базовом классе он может получить Извлеченного экземпляра в комплекте с производным типом , просто путем литья (либо static_cast или Dynamic_cast Работа):

template<class Derived>
struct BaseCRTP {
  void call_foo() {
    Derived& self = *static_cast<Derived*>(this);
    self.foo();
  }
};

struct Example : BaseCRTP<Example> {
  void foo() { cout << "foo()\n"; }
};

В ЭТОМКЕ Call_foo был введен в полученный класс с полным доступом к членам полученного класса.

Не стесняйтесь редактировать и добавлять конкретные примеры использования, возможно, для , так как посты .

34
ответ дан 24 November 2019 в 17:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: