Каковы часто недооцененные понятия в C++? [закрытый]

Если вы не уверены, что делаете, используйте '=='. Если у вас есть немного больше знаний об этом, вы можете использовать «is» для известных объектов, таких как «None».

В противном случае вы будете удивлены, почему все не работает и почему это происходит:

>>> a = 1
>>> b = 1
>>> b is a
True
>>> a = 6000
>>> b = 6000
>>> b is a
False

Я даже не уверен, что некоторые вещи гарантированно останутся неизменными между различными версиями / реализациями python.

33
задан 3 revs, 3 users 100% 18 February 2009 в 12:50
поделиться

36 ответов

C++ не является C с классами!

И нет никакого языка под названием C/C++. Все спускается оттуда.

80
ответ дан 27 November 2019 в 17:21
поделиться
  • , Что анонимные пространства имен почти всегда, что действительно требуется, когда люди делают статические переменные в C++
  • При создании заголовочных файлов библиотеки, pimpl идиома ( http://www.gotw.ca/gotw/024.htm ) должна использоваться почти для всех закрытых функций и участников для помощи в управлении зависимостью
1
ответ дан 27 November 2019 в 17:21
поделиться

указатель А является итератором, но итератор является не всегда указателем

, Это - также часто недооцененное понятие. Указатель на объект является итератором произвольного доступа: Это может быть увеличено/постепенно уменьшено произвольной суммой элементов и может быть считано и записано. Однако класс итератора, который имеет перегрузки оператора, делающие, которые выполняют те требования также. Таким образом, это - также итератор, но является, конечно, не указателем.

я помню, что один из моих прошлых учителей C++ учил (неправильно), что Вы получаете указатель на элемент вектора, если Вы делаете vec.begin(). Он на самом деле принимал - не зная - что вектор реализует свои итераторы с помощью указателей.

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

C++ не является типичным объектно-ориентированным языком.

не верят мне? посмотрите на STL, путь больше шаблонов, чем объекты.

почти невозможно использовать способы Java/C# написать объектно-ориентированный код; это просто не работает.

  • В программировании Java/C#, существует много из new луг, много вспомогательных объектов, которые реализуют некоторую единственную связную функциональность.
  • В C++, любой объект new редактор должен быть удален, но всегда существует проблема того, кто владеет объектом
  • В результате, объекты имеют тенденцию быть созданными на стеке
  • , Но когда Вы делаете это, необходимо скопировать их вокруг все время, если Вы собираетесь раздать их к другим функциям/объектам, таким образом тратя впустую большую производительность, которая, как говорят, достигается с неуправляемой средой C++
  • После понимания, что, необходимо думать о других способах организовать код
  • , Вы могли бы закончить тем, что делали вещи процедурный путь, или использовать идиомы метапрограммирования как интеллектуальные указатели
  • На данном этапе Вы поняли, что OO в C++ не может использоваться тот же путь, как это используется в Java/C#

Q.E.D.

, Если Вы настаиваете на том, чтобы делать ООП с указателями, Вы будете обычно иметь большим (гигантский!) классы, с ясно определенными отношениями владения между объектами избежать утечек памяти. И затем даже если Вы делаете это, Вы уже слишком далеки от идиомы Java/C# ООП.

На самом деле я составил термин "объектно-ориентированный", и я могу сказать Вам, что не имел C++ в виду.
- Alan Kay (нажимают на ссылку, это - видео, кавычка в 10:33)

, Хотя с пуристской точки зрения (например, Alan Kay), даже Java и C# далеки от истинного ООП

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

структуры C VS структуры C++ часто неправильно понимается.

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

C++ не является C со строкой и вектором!

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

std::vector не создает элементы, когда резерв используется

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

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

Выравнивание памяти.

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

Я думаю, что самое недооцененное понятие о C++ - то, почему это существует и какова его цель. Часто под огнем сверху (Java, C# и т.д.) и от ниже (C). C++ имеет способность работать близко к машине для контакта с вычислительной сложностью и механизмами абстракции для управления доменной сложностью.

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

, Если функция принимает, указатель на указатель, void* все еще сделает это

, я видел, что понятие пустой указатель часто путается. Считается, что, если у Вас есть указатель, Вы используете void*, и если у Вас есть указатель на указатель, Вы используете void**. Но Вы можете и должны в обоих случаях использовать void*. void** не имеет специальных свойств, который void* имеет.

Это - специальное свойство, которое void* может также быть присвоено указатель на указатель и при бросании исходное значение получено.

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

Заголовки и файлы реализации

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

Очень похожий на те вопросы то, почему важно иметь защита заголовка .

7
ответ дан 27 November 2019 в 17:21
поделиться
  • Указатели на участников и указатели на функции членства.
  • шаблонные параметры Нетипа.
  • Множественное наследование, особенно виртуальные базовые классы и совместно использованные базовые объекты.
  • Порядок конструкции и разрушения, состояния виртуальных функций посреди построения промежуточного базового класса.
  • безопасность Броска и переменные размеры. Нет, Вы не можете предположить, что sizeof(void *) == sizeof(int) (или любой другой тип в этом отношении, если портативный заголовок конкретно не гарантирует это) в портативном коде.
  • Адресная арифметика с указателями.
8
ответ дан 27 November 2019 в 17:21
поделиться

Я все еще не добираюсь, почему вектор не имеет pop_front и того, что я не могу отсортировать (list.begin (), list.end ())..

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

Существует несколько вещей, которыми люди, кажется, постоянно смущаются или понятия не имеют о:

  1. Указатели, особенно указатели функции и несколько указателей (например, интервал (*) (пусто*), пустой ***)

  2. ключевое слово константы и правильность константы (например, что является различием между символом константы*, символ* константа и символом константы* константа, и что действительно освобождает класс:: участник () константа; средний?)

  3. Выделение памяти (например, каждый указатель new'ed должен быть удален, malloc/free, не должно быть смешано с новым/удаляют, когда использовать, удаляют [] вместо, удаляют, почему функции C все еще полезны (например, расширьтесь (), перевыделение ()))

  4. Объем (т.е. что можно использовать {} самостоятельно для создания нового объема для имен переменной, а не так же, как часть если, для и т.д....)

  5. Операторы переключения. (например, не понимая, что они могут оптимизировать также (или лучше в некоторых случаях), чем цепочки IFS, не понимание проваливается и его практическое применение (развертывание цикла как пример) или что существует случай по умолчанию)

  6. Соглашения о вызовах (например, каково различие между cdecl и stdcall, как Вы реализовали бы функцию Паскаля, почему это даже имеет значение?)

  7. Наследование и множественное наследование и, в более общем плане, вся парадигма OO.

  8. Встроенный ассемблер, поскольку это обычно реализуется, не является частью C++.

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

классик среди новичков к C++ от c:

путают delete и delete[]

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

другой классический отказ среди всех уровней опыта при использовании C API:

std::string helloString = "hello world";
printf("%s\n", helloString);

вместо:

printf("%s\n", helloString.c_str());

это происходит со мной каждую неделю. Вы могли использовать потоки, но иногда необходимо иметь дело с подобными printf API.

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

C++ является языком мультипарадигмы. Многие люди связывают C++ строго с ООП.

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

Учитывая это:

int x = sizeof(char);

, что значение X?

ответ, который Вы часто слышите, является иждивенцем на уровне понимания спецификации.

  1. Новичок - x является тем, потому что символы всегда являются восемью битовыми значениями.
  2. Промежуточное звено - это зависит от реализации компилятора, символы могли быть форматом UTF16.
  3. Эксперт - x один и всегда будет тем, так как символ является самой маленькой адресуемой единицей памяти, и sizeof определяет количество единиц памяти, требуемой сохранить экземпляр типа. Таким образом в системе, где символ составляет восемь битов, 32 битовых значения будут иметь sizeof 4; но в системе, где символ составляет 16 битов, 32 битовых значения будут иметь sizeof 2.

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

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

Вот некоторые:

  1. Используя шаблоны для реализации полиморфизма без vtables, Г la ATL.
  2. Логичный const - мыс по сравнению с фактическим const - мыс в памяти. Когда использовать mutable ключевое слово.
<час>

ПОДТВЕРЖДЕНИЕ: Спасибо за исправление моей ошибки, spoulson.

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

Вот больше:

  1. Виртуальное наследование (не виртуальные методы): На самом деле я не понимаю это вообще! (этим я подразумеваю, что не знаю, как это реализовано)
  2. Объединения, участники которых являются объектами, соответствующие классы которых имеют нетривиальных конструкторов.
12
ответ дан 27 November 2019 в 17:21
поделиться

Вот важное понятие в C++, о котором часто забывают:

C++ не должен просто использоваться как объектно-ориентированный язык, такой как Java или C#. Вдохновите себя от STL и напишите общий код.

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

Массивы не являются указателями

, Они отличаются. Так &array не указатель на указатель, а указатель на массив. Это - самое недооцененное понятие и в C и в C++, по-моему. У Вас должно быть посещение всех, что они ТАК отвечают, что говорят для передачи 2-х массивов как type**!

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

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

  1. Это может быть статическая функция членства или членская переменная.
  2. Это может быть статическая переменная или функция, объявленная в объеме пространства имен.
  3. Это может быть статическая переменная, объявленная в функции.
13
ответ дан 27 November 2019 в 17:21
поделиться

Злоупотребление наследованием, не связанным с полиморфизмом. Большую часть времени, если Вы действительно не используете полиморфизм во время выполнения, состав или статический полиморфизм (т.е. шаблоны) лучше.

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

Самое пагубное понятие, которое я видел, - то, что это нужно рассматривать как C с некоторыми дополнениями. На самом деле, с современными системами C++, это нужно рассматривать как другой язык, и большинство C ++-bashing, которые я вижу, основано на модели "C with add-ons".

Для упоминания некоторых проблем:

, В то время как, вероятно, необходимо знать различие между delete и delete[], Вы не должны обычно писать ни одному. Используйте интеллектуальные указатели и std::vector<>.

На самом деле, необходимо использовать * только редко. Используйте станд.:: строка для строк. (Да, это плохо разработано. Используйте его так или иначе.)

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

В целом, элементы данных класса не должны быть непосредственно видимы, или будучи public или при наличии методов считывания и методов set. Существуют исключения (такие как X и Y в классе точки), но они - исключения и должны считаться как таковыми.

И большой: нет такого языка как C/C++. Возможно записать программы, которые могут скомпилировать правильно под любым языком, но такие программы не являются хорошим C++ и обычно не являются хорошим C. Языки отличались начиная с Stroustrup, запущенного, продолжая работать "C с Классами", и менее подобны теперь чем когда-либо. Используя "C/C++", поскольку имя языка является презумпцией доказательства, что пользователь не знает то, о чем он говорит. C++, правильно используемый, больше не как C, чем Java или C#.

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

В порядке убывания:

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

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

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

Различие между присвоением и инициализацией:

string s = "foo";    // initialisation
s = "bar";           // assignment

Инициализация всегда использует конструкторов, присвоение всегда использует оператор =

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

Бесплатные функции не плохи просто, потому что они не в классе , C++ не является одним только языком ООП, но полагается на целую стопку методов.

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

Это также отражается на языке: основанное на диапазоне для цикла в C++0x (следующая версия C++, выпущенная очень скоро), будет основано на бесплатных вызовах функции. Это доберется, начинаются / конечные итераторы путем вызывания бесплатных функций begin и end.

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

Тот C++ делает , имеют автоматическое управление ресурсами.

(Большинство людей, которые утверждают, что C++ не имеет попытки управления памятью использовать новый и удалить слишком много, не понимая, что, если они позволили C++ управлять ресурсом сами, задача становится намного легче).

Пример: (Сделанный с составленным API, потому что у меня нет времени для проверки документов теперь)

// C++
void DoSomething()
{
  File file("/tmp/dosomething", "rb");
  ... do stuff with file...
  // file is automatically free'ed and closed.
}

// C#
public void DoSomething()
{
  File file = new File("/tmp/dosomething", "rb");
  ... do stuff with file...

  // file is NOT automatically closed.
  // What if the caller calls DoSomething() in a tight loop?
  // C# requires you to be aware of the implementation of the File class
  // and forces you to accommodate, thus voiding implementation-hiding
  // principles.
  // Approaches may include:
  // 1) Utilizing the IDisposable pattern.
  // 2) Utilizing try-finally guards, which quickly gets messy.
  // 3) The nagging doubt that you've forgotten something /somewhere/ in your
  //    1 million loc project.
  // 4) The realization that point #3 can not be fixed by fixing the File
  //    class.
}
40
ответ дан 27 November 2019 в 17:21
поделиться

Указатели.

Разыменование указателей. Или до . или до ->

Адрес использования & для того, когда указатель требуется.

Функции, которые берут параметрические усилители ссылкой specifing & в подписи.

Указатель на указатели на указатели *** или указатели ссылкой void someFunc(int *& arg)

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

NULL всегда равен нулю.

Многие путают NULL с адресом и поэтому думают, что он не обязательно равен нулю, если платформа имеет другой адрес нулевого указателя. .

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

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

Почему [b] то же самое как b?

хорошо, не действительно Общий вопрос, но это подошло в классе, который я преподавал однажды...

0
ответ дан 27 November 2019 в 17:21
поделиться
Другие вопросы по тегам:

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